home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.006 / xemacs-1 / lib / xemacs-19.13 / lisp / comint / gud.el < prev    next >
Encoding:
Text File  |  1995-05-13  |  106.8 KB  |  3,230 lines

  1. ;;; gud.el --- Grand Unified Debugger mode for gdb, sdb, dbx, or xdb
  2. ;;;            under Emacs
  3.  
  4. ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
  5. ;; Maintainer: FSF
  6. ;; Version: 1.3
  7. ;; Keywords: c, unix, tools, debugging
  8.  
  9. ;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  10.  
  11. ;; This file is part of XEmacs.
  12.  
  13. ;; XEmacs is free software; you can redistribute it and/or modify it
  14. ;; under the terms of the GNU General Public License as published by
  15. ;; the Free Software Foundation; either version 2, or (at your option)
  16. ;; any later version.
  17.  
  18. ;; XEmacs is distributed in the hope that it will be useful, but
  19. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  21. ;; General Public License for more details.
  22.  
  23. ;; You should have received a copy of the GNU General Public License
  24. ;; along with XEmacs; see the file COPYING.  If not, write to the Free
  25. ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  
  27. ;;; Commentary:
  28.  
  29. ;; The ancestral gdb.el was by W. Schelter <wfs@rascal.ics.utexas.edu>
  30. ;; It was later rewritten by rms.  Some ideas were due to Masanobu. 
  31. ;; Grand Unification (sdb/dbx support) by Eric S. Raymond <esr@thyrsus.com>
  32. ;; The overloading code was then rewritten by Barry Warsaw <bwarsaw@cen.com>,
  33. ;; who also hacked the mode to use comint.el.  Shane Hartman <shane@spr.com>
  34. ;; added support for xdb (HPUX debugger).
  35.  
  36. ;; Cygnus Support added support for gdb's --annotate=2.
  37.  
  38. ;;; Code:
  39.  
  40. (require 'comint)
  41. (require 'etags)
  42.  
  43. ;; ======================================================================
  44. ;; GUD commands must be visible in C buffers visited by GUD
  45.  
  46. (defvar gud-key-prefix "\C-x\C-a"
  47.   "Prefix of all GUD commands valid in C buffers.")
  48.  
  49. (global-set-key (concat gud-key-prefix "\C-l") 'gud-refresh)
  50. (global-set-key "\C-x " 'gud-break)    ;; backward compatibility hack
  51.  
  52. ;; ======================================================================
  53. ;; the overloading mechanism
  54.  
  55. (defun gud-overload-functions (gud-overload-alist)
  56.   "Overload functions defined in GUD-OVERLOAD-ALIST.
  57. This association list has elements of the form
  58.      (ORIGINAL-FUNCTION-NAME  OVERLOAD-FUNCTION)"
  59.   (mapcar
  60.    (function (lambda (p) (fset (car p) (symbol-function (cdr p)))))
  61.    gud-overload-alist))
  62.  
  63. (defun gud-massage-args (file args)
  64.   (error "GUD not properly entered."))
  65.  
  66. (defun gud-marker-filter (str)
  67.   (error "GUD not properly entered."))
  68.  
  69. (defun gud-find-file (f)
  70.   (error "GUD not properly entered."))
  71.  
  72. ;; ======================================================================
  73. ;; command definition
  74.  
  75. ;; This macro is used below to define some basic debugger interface commands.
  76. ;; Of course you may use `gud-def' with any other debugger command, including
  77. ;; user defined ones.
  78.  
  79. ;; A macro call like (gud-def FUNC NAME KEY DOC) expands to a form
  80. ;; which defines FUNC to send the command NAME to the debugger, gives
  81. ;; it the docstring DOC, and binds that function to KEY in the GUD
  82. ;; major mode.  The function is also bound in the global keymap with the
  83. ;; GUD prefix.
  84.  
  85. (defmacro gud-def (func cmd key &optional doc)
  86.   "Define FUNC to be a command sending STR and bound to KEY, with
  87. optional doc string DOC.  Certain %-escapes in the string arguments
  88. are interpreted specially if present.  These are:
  89.  
  90.   %f    name (without directory) of current source file. 
  91.   %d    directory of current source file. 
  92.   %l    number of current source line
  93.   %e    text of the C lvalue or function-call expression surrounding point.
  94.   %a    text of the hexadecimal address surrounding point
  95.   %p    prefix argument to the command (if any) as a number
  96.  
  97.   The `current' source file is the file of the current buffer (if
  98. we're in a C file) or the source file current at the last break or
  99. step (if we're in the GUD buffer).
  100.   The `current' line is that of the current buffer (if we're in a
  101. source file) or the source line number at the last break or step (if
  102. we're in the GUD buffer)."
  103.   (list 'progn
  104.     (list 'defun func '(arg)
  105.           (or doc "")
  106.           '(interactive "p")
  107.           (list 'gud-call cmd 'arg))
  108.     (if key
  109.         (list 'define-key
  110.           '(current-local-map)
  111.           (concat "\C-c" key)
  112.           (list 'quote func)))
  113.     (if key
  114.         (list 'global-set-key
  115.           (list 'concat 'gud-key-prefix key)
  116.           (list 'quote func)))))
  117.  
  118. ;; Where gud-display-frame should put the debugging arrow.  This is
  119. ;; set by the marker-filter, which scans the debugger's output for
  120. ;; indications of the current program counter.
  121. (defvar gud-last-frame nil)
  122.  
  123. ;; Used by gud-refresh, which should cause gud-display-frame to redisplay
  124. ;; the last frame, even if it's been called before and gud-last-frame has
  125. ;; been set to nil.
  126. (defvar gud-last-last-frame nil)
  127.  
  128. ;; All debugger-specific information is collected here.
  129. ;; Here's how it works, in case you ever need to add a debugger to the mode.
  130. ;;
  131. ;; Each entry must define the following at startup:
  132. ;;
  133. ;;<name>
  134. ;; comint-prompt-regexp
  135. ;; gud-<name>-massage-args
  136. ;; gud-<name>-marker-filter
  137. ;; gud-<name>-find-file
  138. ;;
  139. ;; The job of the massage-args method is to modify the given list of
  140. ;; debugger arguments before running the debugger.
  141. ;;
  142. ;; The job of the marker-filter method is to detect file/line markers in
  143. ;; strings and set the global gud-last-frame to indicate what display
  144. ;; action (if any) should be triggered by the marker.  Note that only
  145. ;; whatever the method *returns* is displayed in the buffer; thus, you
  146. ;; can filter the debugger's output, interpreting some and passing on
  147. ;; the rest.
  148. ;;
  149. ;; The job of the find-file method is to visit and return the buffer indicated
  150. ;; by the car of gud-tag-frame.  This may be a file name, a tag name, or
  151. ;; something else.
  152.  
  153. ;; ======================================================================
  154. ;; gdb functions
  155.  
  156. ;;; History of argument lists passed to gdb.
  157. (defvar gud-gdb-history nil)
  158.  
  159. (defun gud-gdb-massage-args (file args)
  160.   (cons "--annotate=2" (cons file args)))
  161.  
  162.  
  163. ;;
  164. ;; In this world, there are gdb instance objects (of unspecified 
  165. ;; representation) and buffers associated with those objects.
  166. ;;
  167.  
  168. ;; 
  169. ;; gdb-instance objects
  170. ;; 
  171.  
  172. (defun make-gdb-instance (proc)
  173.   "Create a gdb instance object from a gdb process."
  174.   (setq last-proc proc)
  175.   (let ((instance (cons 'gdb-instance proc)))
  176.     (save-excursion
  177.       (set-buffer (process-buffer proc))
  178.       (setq gdb-buffer-instance instance)
  179.       (progn
  180.     (mapcar 'make-variable-buffer-local gdb-instance-variables)
  181.     (setq gdb-buffer-type 'gud)
  182.     ;; If we're taking over the buffer of another process,
  183.     ;; take over it's ancillery buffers as well.
  184.     ;;
  185.     (let ((dead (or old-gdb-buffer-instance)))
  186.       (mapcar
  187.        (function
  188.         (lambda (b)
  189.           (progn
  190.         (set-buffer b)
  191.         (if (eq dead gdb-buffer-instance)
  192.             (setq gdb-buffer-instance instance)))))
  193.          (buffer-list)))))
  194.     instance))
  195.  
  196. (defun gdb-instance-process (inst) (cdr inst))
  197.  
  198. ;;; The list of instance variables is built up by the expansions of
  199. ;;; DEF-GDB-VARIABLE
  200. ;;;
  201. (defvar gdb-instance-variables '()
  202.   "A list of variables that are local to the gud buffer associated
  203. with a gdb instance.") 
  204.  
  205. (defmacro def-gdb-variable
  206.   (name accessor setter &optional default doc)
  207.   (`
  208.    (progn
  209.      (defvar (, name) (, default) (, (or doc "undocumented")))
  210.      (if (not (memq '(, name) gdb-instance-variables))
  211.      (setq gdb-instance-variables
  212.            (cons '(, name) gdb-instance-variables)))
  213.      (, (and accessor
  214.          (`
  215.           (defun (, accessor) (instance)
  216.         (let
  217.             ((buffer (gdb-get-instance-buffer instance 'gud)))
  218.           (and buffer
  219.                (save-excursion
  220.              (set-buffer buffer)
  221.              (, name))))))))
  222.      (, (and setter
  223.          (`
  224.           (defun (, setter) (instance val)
  225.         (let
  226.             ((buffer (gdb-get-instance-buffer instance 'gud)))
  227.           (and buffer
  228.                (save-excursion
  229.              (set-buffer buffer)
  230.              (setq (, name) val)))))))))))
  231.  
  232. (defmacro def-gdb-var (root-symbol &optional default doc)
  233.   (let* ((root (symbol-name root-symbol))
  234.      (accessor (intern (concat "gdb-instance-" root)))
  235.      (setter (intern (concat "set-gdb-instance-" root)))
  236.      (var-name (intern (concat "gdb-" root))))
  237.     (` (def-gdb-variable
  238.      (, var-name) (, accessor) (, setter)
  239.      (, default) (, doc)))))
  240.  
  241. (def-gdb-var buffer-instance nil
  242.   "In an instance buffer, the buffer's instance.")
  243.  
  244. (def-gdb-var buffer-type nil
  245.   "One of the symbols bound in gdb-instance-buffer-rules")
  246.  
  247. (def-gdb-var burst ""
  248.   "A string of characters from gdb that have not yet been processed.")
  249.  
  250. (def-gdb-var input-queue ()
  251.   "A list of high priority gdb command objects.")
  252.  
  253. (def-gdb-var idle-input-queue ()
  254.   "A list of low priority gdb command objects.")
  255.  
  256. (def-gdb-var prompting nil
  257.   "True when gdb is idle with no pending input.")
  258.  
  259. (def-gdb-var output-sink 'user
  260.   "The disposition of the output of the current gdb command.
  261. Possible values are these symbols:
  262.  
  263.     user -- gdb output should be copied to the gud buffer 
  264.             for the user to see.
  265.  
  266.     inferior -- gdb output should be copied to the inferior-io buffer
  267.  
  268.     pre-emacs -- output should be ignored util the post-prompt
  269.                  annotation is received.  Then the output-sink
  270.          becomes:...
  271.     emacs -- output should be collected in the partial-output-buffer
  272.          for subsequent processing by a command.  This is the
  273.          disposition of output generated by commands that
  274.          gud mode sends to gdb on its own behalf.
  275.     post-emacs -- ignore input until the prompt annotation is 
  276.           received, then go to USER disposition.
  277. ")
  278.  
  279. (def-gdb-var current-item nil
  280.   "The most recent command item sent to gdb.")
  281.  
  282. (def-gdb-var pending-triggers '()
  283.   "A list of trigger functions that have run later than their output
  284. handlers.")
  285.  
  286. (defun in-gdb-instance-context (instance form)
  287.   "Funcall `form' in the gud buffer of `instance'"
  288.   (save-excursion
  289.     (set-buffer (gdb-get-instance-buffer instance 'gud))
  290.     (funcall form)))
  291.  
  292. ;; end of instance vars
  293.  
  294. ;;
  295. ;; finding instances
  296. ;;
  297.  
  298. (defun gdb-proc->instance (proc)
  299.   (save-excursion
  300.     (set-buffer (process-buffer proc))
  301.     gdb-buffer-instance))
  302.  
  303. (defun gdb-mru-instance-buffer ()
  304.   "Return the most recently used (non-auxiliary) gdb gud buffer."
  305.   (save-excursion
  306.     (gdb-goto-first-gdb-instance (buffer-list))))
  307.  
  308. (defun gdb-goto-first-gdb-instance (blist)
  309.   "Use gdb-mru-instance-buffer -- not this."
  310.   (and blist
  311.        (progn
  312.      (set-buffer (car blist))
  313.      (or (and gdb-buffer-instance
  314.           (eq gdb-buffer-type 'gud)
  315.           (car blist))
  316.          (gdb-goto-first-gdb-instance (cdr blist))))))
  317.  
  318. (defun buffer-gdb-instance (buf)
  319.   (save-excursion
  320.     (set-buffer buf)
  321.     gdb-buffer-instance))
  322.  
  323. (defun gdb-needed-default-instance ()
  324.   "Return the most recently used gdb instance or signal an error."
  325.   (let ((buffer (gdb-mru-instance-buffer)))
  326.     (or (and buffer (buffer-gdb-instance buffer))
  327.     (error "No instance of gdb found."))))
  328.  
  329. (defun gdb-instance-target-string (instance)
  330.   "The apparent name of the program being debugged by a gdb instance.
  331. For sure this the root string used in smashing together the gud 
  332. buffer's name, even if that doesn't happen to be the name of a 
  333. program."
  334.   (in-gdb-instance-context
  335.    instance
  336.    (function (lambda () gud-target-name))))
  337.  
  338.  
  339.  
  340. ;;
  341. ;; Instance Buffers.
  342. ;;
  343.  
  344. ;; More than one buffer can be associated with a gdb instance.
  345. ;;
  346. ;; Each buffer has a TYPE -- a symbol that identifies the function
  347. ;; of that particular buffer.
  348. ;;
  349. ;; The usual gud interaction buffer is given the type `gud' and
  350. ;; is constructed specially.  
  351. ;;
  352. ;; Others are constructed by gdb-get-create-instance-buffer and 
  353. ;; named according to the rules set forth in the gdb-instance-buffer-rules-assoc
  354.  
  355. (defun gdb-get-instance-buffer (instance key)
  356.   "Return the instance buffer for `instance' tagged with type `key'.
  357. The key should be one of the cars in `gdb-instance-buffer-rules-assoc'."
  358.   (save-excursion
  359.     (gdb-look-for-tagged-buffer instance key (buffer-list))))
  360.  
  361. (defun gdb-get-create-instance-buffer (instance key)
  362.   "Create a new gdb instance buffer of the type specified by `key'.
  363. The key should be one of the cars in `gdb-instance-buffer-rules-assoc'."
  364.   (or (gdb-get-instance-buffer instance key)
  365.       (let* ((rules (assoc key gdb-instance-buffer-rules-assoc))
  366.          (name (funcall (gdb-rules-name-maker rules) instance))
  367.          (new (get-buffer-create name)))
  368.     (save-excursion
  369.       (set-buffer new)
  370.       (make-variable-buffer-local 'gdb-buffer-type)
  371.       (setq gdb-buffer-type key)
  372.       (make-variable-buffer-local 'gdb-buffer-instance)
  373.       (setq gdb-buffer-instance instance)
  374.       (if (cdr (cdr rules))
  375.           (funcall (car (cdr (cdr rules)))))
  376.       new))))
  377.  
  378. (defun gdb-rules-name-maker (rules) (car (cdr rules)))
  379.  
  380. (defun gdb-look-for-tagged-buffer (instance key bufs)
  381.   (let ((retval nil))
  382.     (while (and (not retval) bufs)
  383.       (set-buffer (car bufs))
  384.       (if (and (eq gdb-buffer-instance instance)
  385.            (eq gdb-buffer-type key))
  386.       (setq retval (car bufs)))
  387.       (setq bufs (cdr bufs))
  388.       )
  389.     retval))
  390.  
  391. (defun gdb-instance-buffer-p (buf)
  392.   (save-excursion
  393.     (set-buffer buf)
  394.     (and gdb-buffer-type
  395.      (not (eq gdb-buffer-type 'gud)))))
  396.  
  397. ;;
  398. ;; This assoc maps buffer type symbols to rules.  Each rule is a list of
  399. ;; at least one and possible more functions.  The functions have these
  400. ;; roles in defining a buffer type:
  401. ;;
  402. ;;     NAME - take an instance, return a name for this type buffer for that 
  403. ;;          instance.
  404. ;; The remaining function(s) are optional:
  405. ;;
  406. ;;     MODE - called in new new buffer with no arguments, should establish
  407. ;;          the proper mode for the buffer.
  408. ;;
  409.  
  410. (defvar gdb-instance-buffer-rules-assoc '())
  411.  
  412. (defun gdb-set-instance-buffer-rules (buffer-type &rest rules)
  413.   (let ((binding (assoc buffer-type gdb-instance-buffer-rules-assoc)))
  414.     (if binding
  415.     (setcdr binding rules)
  416.       (setq gdb-instance-buffer-rules-assoc
  417.         (cons (cons buffer-type rules)
  418.           gdb-instance-buffer-rules-assoc)))))
  419.  
  420. (gdb-set-instance-buffer-rules 'gud 'error) ; gud buffers are an exception to the rules
  421.  
  422. ;;
  423. ;; partial-output buffers
  424. ;;
  425. ;; These accumulate output from a command executed on
  426. ;; behalf of emacs (rather than the user).  
  427. ;;
  428.  
  429. (gdb-set-instance-buffer-rules 'gdb-partial-output-buffer
  430.                    'gdb-partial-output-name)
  431.  
  432. (defun gdb-partial-output-name (instance)
  433.   (concat "*partial-output-"
  434.       (gdb-instance-target-string instance)
  435.       "*"))
  436.  
  437.  
  438. (gdb-set-instance-buffer-rules 'gdb-inferior-io
  439.                    'gdb-inferior-io-name
  440.                    'gud-inferior-io-mode)
  441.  
  442. (defun gdb-inferior-io-name (instance)
  443.   (concat "*input/output of "
  444.       (gdb-instance-target-string instance)
  445.       "*"))
  446.  
  447. (defvar gdb-inferior-io-mode-map (copy-keymap comint-mode-map))
  448. (define-key gdb-inferior-io-mode-map "\C-c\C-c" 'gdb-inferior-io-interrupt)
  449. (define-key gdb-inferior-io-mode-map "\C-c\C-z" 'gdb-inferior-io-stop)
  450. (define-key gdb-inferior-io-mode-map "\C-c\C-\\" 'gdb-inferior-io-quit)
  451. (define-key gdb-inferior-io-mode-map "\C-c\C-d" 'gdb-inferior-io-eof)
  452.  
  453. (defun gud-inferior-io-mode ()
  454.   "Major mode for gud inferior-io.
  455.  
  456. \\{comint-mode-map}"
  457.   ;; We want to use comint because it has various nifty and familiar
  458.   ;; features.  We don't need a process, but comint wants one, so create
  459.   ;; a dummy one.
  460.   (make-comint (substring (buffer-name) 1 (- (length (buffer-name)) 1))
  461.            "/bin/cat")
  462.   (setq major-mode 'gud-inferior-io-mode)
  463.   (setq mode-name "Debuggee I/O")
  464.   (setq comint-input-sender 'gud-inferior-io-sender)
  465. )
  466.  
  467. (defun gud-inferior-io-sender (proc string)
  468.   (save-excursion
  469.     (set-buffer (process-buffer proc))
  470.     (let ((instance gdb-buffer-instance))
  471.       (set-buffer (gdb-get-instance-buffer instance 'gud))
  472.       (let ((gud-proc (get-buffer-process (current-buffer))))
  473.     (process-send-string gud-proc string)
  474.     (process-send-string gud-proc "\n")
  475.     ))
  476.     ))
  477.  
  478. (defun gdb-inferior-io-interrupt (instance)
  479.   "Interrupt the program being debugged."
  480.   (interactive (list (gdb-needed-default-instance)))
  481.   (interrupt-process
  482.    (get-buffer-process (gdb-get-instance-buffer instance 'gud)) comint-ptyp))
  483.  
  484. (defun gdb-inferior-io-quit (instance)
  485.   "Send quit signal to the program being debugged."
  486.   (interactive (list (gdb-needed-default-instance)))
  487.   (quit-process
  488.    (get-buffer-process (gdb-get-instance-buffer instance 'gud)) comint-ptyp))
  489.  
  490. (defun gdb-inferior-io-stop (instance)
  491.   "Stop the program being debugged."
  492.   (interactive (list (gdb-needed-default-instance)))
  493.   (stop-process
  494.    (get-buffer-process (gdb-get-instance-buffer instance 'gud)) comint-ptyp))
  495.  
  496. (defun gdb-inferior-io-eof (instance)
  497.   "Send end-of-file to the program being debugged."
  498.   (interactive (list (gdb-needed-default-instance)))
  499.   (process-send-eof
  500.    (get-buffer-process (gdb-get-instance-buffer instance 'gud))))
  501.  
  502.  
  503. ;;
  504. ;; gdb communications
  505. ;;
  506.  
  507. ;; INPUT: things sent to gdb
  508. ;;
  509. ;; Each instance has a high and low priority 
  510. ;; input queue.  Low priority input is sent only 
  511. ;; when the high priority queue is idle.
  512. ;;
  513. ;; The queues are lists.  Each element is either 
  514. ;; a string (indicating user or user-like input)
  515. ;; or a list of the form:
  516. ;;
  517. ;;    (INPUT-STRING  HANDLER-FN)
  518. ;;
  519. ;;
  520. ;; The handler function will be called from the 
  521. ;; partial-output buffer when the command completes.
  522. ;; This is the way to write commands which 
  523. ;; invoke gdb commands autonomously.
  524. ;;
  525. ;; These lists are consumed tail first.
  526. ;;
  527.  
  528. (defun gdb-send (proc string)
  529.   "A comint send filter for gdb.
  530. This filter may simply queue output for a later time."
  531.   (let ((instance (gdb-proc->instance proc)))
  532.     (gdb-instance-enqueue-input instance (concat string "\n"))))
  533.  
  534. ;; Note: Stuff enqueued here will be sent to the next prompt, even if it
  535. ;; is a query, or other non-top-level prompt.  To guarantee stuff will get
  536. ;; sent to the top-level prompt, currently it must be put in the idle queue.
  537. ;;                 ^^^^^^^^^
  538. ;; [This should encourage gud extentions that invoke gdb commands to let
  539. ;;  the user go first; it is not a bug.     -t]
  540. ;;
  541.  
  542. (defun gdb-instance-enqueue-input (instance item)
  543.   (if (gdb-instance-prompting instance)
  544.       (progn
  545.     (gdb-send-item instance item)
  546.     (set-gdb-instance-prompting instance nil))
  547.     (set-gdb-instance-input-queue
  548.      instance
  549.      (cons item (gdb-instance-input-queue instance)))))
  550.  
  551. (defun gdb-instance-dequeue-input (instance)
  552.   (let ((queue (gdb-instance-input-queue instance)))
  553.     (and queue
  554.        (if (not (cdr queue))
  555.        (let ((answer (car queue)))
  556.          (set-gdb-instance-input-queue instance '())
  557.          answer)
  558.      (gdb-take-last-elt queue)))))
  559.  
  560. (defun gdb-instance-enqueue-idle-input (instance item)
  561.   (if (and (gdb-instance-prompting instance)
  562.        (not (gdb-instance-input-queue instance)))
  563.       (progn
  564.     (gdb-send-item instance item)
  565.     (set-gdb-instance-prompting instance nil))
  566.     (set-gdb-instance-idle-input-queue
  567.      instance
  568.      (cons item (gdb-instance-idle-input-queue instance)))))
  569.  
  570. (defun gdb-instance-dequeue-idle-input (instance)
  571.   (let ((queue (gdb-instance-idle-input-queue instance)))
  572.     (and queue
  573.        (if (not (cdr queue))
  574.        (let ((answer (car queue)))
  575.          (set-gdb-instance-idle-input-queue instance '())
  576.          answer)
  577.      (gdb-take-last-elt queue)))))
  578.  
  579. ; Don't use this in general.
  580. (defun gdb-take-last-elt (l)
  581.   (if (cdr (cdr l))
  582.       (gdb-take-last-elt (cdr l))
  583.     (let ((answer (car (cdr l))))
  584.       (setcdr l '())
  585.       answer)))
  586.  
  587.  
  588. ;;
  589. ;; output -- things gdb prints to emacs
  590. ;;
  591. ;; GDB output is a stream interrupted by annotations.
  592. ;; Annotations can be recognized by their beginning
  593. ;; with \C-j\C-z\C-z<tag><opt>\C-j
  594. ;;
  595. ;; The tag is a string obeying symbol syntax.
  596. ;;
  597. ;; The optional part `<opt>' can be either the empty string
  598. ;; or a space followed by more data relating to the annotation.
  599. ;; For example, the SOURCE annotation is followed by a filename,
  600. ;; line number and various useless goo.  This data must not include
  601. ;; any newlines.
  602. ;;
  603.  
  604.  
  605. (defun gud-gdb-marker-filter (string)
  606.   "A gud marker filter for gdb."
  607.   ;; Bogons don't tell us the process except through scoping crud.
  608.   (let ((instance (gdb-proc->instance proc)))
  609.     (gdb-output-burst instance string)))
  610.  
  611. (defvar gdb-annotation-rules
  612.   '(("frames-invalid" gdb-invalidate-frames)
  613.     ("breakpoints-invalid" gdb-invalidate-breakpoints)
  614.     ("pre-prompt" gdb-pre-prompt)
  615.     ("prompt" gdb-prompt)
  616.     ("commands" gdb-subprompt)
  617.     ("overload-choice" gdb-subprompt)
  618.     ("query" gdb-subprompt)
  619.     ("prompt-for-continue" gdb-subprompt)
  620.     ("post-prompt" gdb-post-prompt)
  621.     ("source" gdb-source)
  622.     ("starting" gdb-starting)
  623.     ("exited" gdb-stopping)
  624.     ("signalled" gdb-stopping)
  625.     ("signal" gdb-stopping)
  626.     ("breakpoint" gdb-stopping)
  627.     ("watchpoint" gdb-stopping)
  628.     ("stopped" gdb-stopped)
  629.     ("display-begin" gdb-display-begin)
  630.     ("display-end" gdb-display-end)
  631.     ("error-begin" gdb-error-begin)
  632.     )
  633.   "An assoc mapping annotation tags to functions which process them.")
  634.  
  635.  
  636. (defun gdb-ignore-annotation (instance args)
  637.   nil)
  638.  
  639. (defconst gdb-source-spec-regexp
  640.   "\\(.*\\):\\([0-9]*\\):[0-9]*:[a-z]*:0x[a-f0-9]*")
  641.  
  642. ;; Do not use this except as an annotation handler."
  643. (defun gdb-source (instance args)
  644.   (string-match gdb-source-spec-regexp args)
  645.   ;; Extract the frame position from the marker.
  646.   (setq gud-last-frame
  647.     (cons
  648.      (substring args (match-beginning 1) (match-end 1))
  649.      (string-to-int (substring args
  650.                    (match-beginning 2)
  651.                    (match-end 2))))))
  652.  
  653. ;; An annotation handler for `prompt'.
  654. ;; This sends the next command (if any) to gdb.
  655. (defun gdb-prompt (instance ignored)
  656.   (let ((sink (gdb-instance-output-sink instance)))
  657.     (cond
  658.      ((eq sink 'user) t)
  659.      ((eq sink 'post-emacs)
  660.       (set-gdb-instance-output-sink instance 'user))
  661.      (t
  662.       (set-gdb-instance-output-sink instance 'user)
  663.       (error "Phase error in gdb-prompt (got %s)" sink))))
  664.   (let ((highest (gdb-instance-dequeue-input instance)))
  665.     (if highest
  666.     (gdb-send-item instance highest)
  667.       (let ((lowest (gdb-instance-dequeue-idle-input instance)))
  668.     (if lowest
  669.         (gdb-send-item instance lowest)
  670.       (progn
  671.         (set-gdb-instance-prompting instance t)
  672.         (gud-display-frame)))))))
  673.  
  674. ;; An annotation handler for non-top-level prompts.
  675. (defun gdb-subprompt (instance ignored)
  676.   (let ((highest (gdb-instance-dequeue-input instance)))
  677.     (if highest
  678.     (gdb-send-item instance highest)
  679.       (set-gdb-instance-prompting instance t))))
  680.  
  681. (defun gdb-send-item (instance item)
  682.   (set-gdb-instance-current-item instance item)
  683.   (if (stringp item)
  684.       (progn
  685.     (set-gdb-instance-output-sink instance 'user)
  686.     (process-send-string (gdb-instance-process instance)
  687.                  item))
  688.     (progn
  689.       (gdb-clear-partial-output instance)
  690.       (set-gdb-instance-output-sink instance 'pre-emacs)
  691.       (process-send-string (gdb-instance-process instance)
  692.                (car item)))))
  693.  
  694. ;; This terminates the collection of output from a previous
  695. ;; command if that happens to be in effect.
  696. (defun gdb-pre-prompt (instance ignored)
  697.   (let ((sink (gdb-instance-output-sink instance)))
  698.     (cond
  699.      ((eq sink 'user) t)
  700.      ((eq sink 'emacs)
  701.       (set-gdb-instance-output-sink instance 'post-emacs)
  702.       (let ((handler
  703.          (car (cdr (gdb-instance-current-item instance)))))
  704.     (save-excursion
  705.       (set-buffer (gdb-get-create-instance-buffer
  706.                instance 'gdb-partial-output-buffer))
  707.       (funcall handler))))
  708.      (t
  709.       (set-gdb-instance-output-sink instance 'user)
  710.       (error "Output sink phase error 1.")))))
  711.  
  712. ;; An annotation handler for `starting'.  This says that I/O for the subprocess
  713. ;; is now the program being debugged, not GDB.
  714. (defun gdb-starting (instance ignored)
  715.   (let ((sink (gdb-instance-output-sink instance)))
  716.     (cond
  717.      ((eq sink 'user)
  718.       (set-gdb-instance-output-sink instance 'inferior)
  719.       ;; FIXME: need to send queued input
  720.       )
  721.      (t (error "Unexpected `starting' annotation")))))
  722.  
  723. ;; An annotation handler for `exited' and other annotations which say that
  724. ;; I/O for the subprocess is now GDB, not the program being debugged.
  725. (defun gdb-stopping (instance ignored)
  726.   (let ((sink (gdb-instance-output-sink instance)))
  727.     (cond
  728.      ((eq sink 'inferior)
  729.       (set-gdb-instance-output-sink instance 'user)
  730.       )
  731.      (t (error "Unexpected stopping annotation")))))
  732.  
  733. ;; An annotation handler for `stopped'.  It is just like gdb-stopping, except
  734. ;; that if we already set the output sink to 'user in gdb-stopping, that is 
  735. ;; fine.
  736. (defun gdb-stopped (instance ignored)
  737.   (let ((sink (gdb-instance-output-sink instance)))
  738.     (cond
  739.      ((eq sink 'inferior)
  740.       (set-gdb-instance-output-sink instance 'user)
  741.       )
  742.      ((eq sink 'user)
  743.       t)
  744.      (t (error "Unexpected stopping annotation")))))
  745.  
  746. ;; An annotation handler for `post-prompt'.
  747. ;; This begins the collection of output from the current
  748. ;; command if that happens to be appropriate."
  749. (defun gdb-post-prompt (instance ignored)
  750.   (if (not (gdb-instance-pending-triggers instance))
  751.       (progn
  752.     (gdb-invalidate-registers instance ignored)
  753.     (gdb-invalidate-locals instance ignored)
  754.     (gdb-invalidate-display instance ignored)))
  755.   (let ((sink (gdb-instance-output-sink instance)))
  756.     (cond
  757.      ((eq sink 'user) t)
  758.      ((eq sink 'pre-emacs)
  759.       (set-gdb-instance-output-sink instance 'emacs))
  760.  
  761.      (t
  762.       (set-gdb-instance-output-sink instance 'user)
  763.       (error "Output sink phase error 3.")))))
  764.  
  765. ;; Handle a burst of output from a gdb instance.
  766. ;; This function is (indirectly) used as a gud-marker-filter.
  767. ;; It must return output (if any) to be insterted in the gud 
  768. ;; buffer.
  769.  
  770. (defun gdb-output-burst (instance string)
  771.   "Handle a burst of output from a gdb instance.
  772. This function is (indirectly) used as a gud-marker-filter.
  773. It must return output (if any) to be insterted in the gud 
  774. buffer."
  775.  
  776.   (save-match-data
  777.     (let (
  778.       ;; Recall the left over burst from last time
  779.       (burst (concat (gdb-instance-burst instance) string))
  780.       ;; Start accumulating output for the gud buffer
  781.       (output ""))
  782.  
  783.       ;; Process all the complete markers in this chunk.
  784.  
  785.       (while (string-match "\n\032\032\\(.*\\)\n" burst)
  786.     (let ((annotation (substring burst
  787.                      (match-beginning 1)
  788.                      (match-end 1))))
  789.         
  790.       ;; Stuff prior to the match is just ordinary output.
  791.       ;; It is either concatenated to OUTPUT or directed
  792.       ;; elsewhere.
  793.       (setq output
  794.         (gdb-concat-output
  795.          instance
  796.          output
  797.          (substring burst 0 (match-beginning 0))))
  798.  
  799.       ;; Take that stuff off the burst.
  800.       (setq burst (substring burst (match-end 0)))
  801.         
  802.       ;; Parse the tag from the annotation, and maybe its arguments.
  803.       (string-match "\\(\\S-*\\) ?\\(.*\\)" annotation)
  804.       (let* ((annotation-type (substring annotation
  805.                          (match-beginning 1)
  806.                          (match-end 1)))
  807.          (annotation-arguments (substring annotation
  808.                           (match-beginning 2)
  809.                           (match-end 2)))
  810.          (annotation-rule (assoc annotation-type
  811.                      gdb-annotation-rules)))
  812.         ;; Call the handler for this annotation.
  813.         (if annotation-rule
  814.         (funcall (car (cdr annotation-rule))
  815.              instance
  816.              annotation-arguments)
  817.           ;; Else the annotation is not recognized.  Ignore it silently,
  818.           ;; so that GDB can add new annotations without causing
  819.           ;; us to blow up.
  820.           ))))
  821.  
  822.  
  823.       ;; Does the remaining text end in a partial line?
  824.       ;; If it does, then keep part of the burst until we get more.
  825.       (if (string-match "\n\\'\\|\n\032\\'\\|\n\032\032.*\\'"
  826.             burst)
  827.       (progn
  828.         ;; Everything before the potential marker start can be output.
  829.         (setq output
  830.           (gdb-concat-output
  831.            instance
  832.            output
  833.            (substring burst 0 (match-beginning 0))))
  834.  
  835.         ;; Everything after, we save, to combine with later input.
  836.         (setq burst (substring burst (match-beginning 0))))
  837.  
  838.     ;; In case we know the burst contains no partial annotations:
  839.     (progn
  840.       (setq output (gdb-concat-output instance output burst))
  841.       (setq burst "")))
  842.  
  843.       ;; Save the remaining burst for the next call to this function.
  844.       (set-gdb-instance-burst instance burst)
  845.       output)))
  846.  
  847. (defun gdb-concat-output (instance so-far new)
  848.   (let ((sink (gdb-instance-output-sink instance)))
  849.     (cond
  850.      ((eq sink 'user) (concat so-far new))
  851.      ((or (eq sink 'pre-emacs) (eq sink 'post-emacs)) so-far)
  852.      ((eq sink 'emacs)
  853.       (gdb-append-to-partial-output instance new)
  854.       so-far)
  855.      ((eq sink 'inferior)
  856.       (gdb-append-to-inferior-io instance new)
  857.       so-far)
  858.      (t (error "Bogon output sink %S" sink)))))
  859.  
  860. (defun gdb-append-to-partial-output (instance string)
  861.   (save-excursion
  862.     (buffer-disable-undo ; Don't need undo in partial output buffer
  863.      (set-buffer
  864.       (gdb-get-create-instance-buffer
  865.        instance 'gdb-partial-output-buffer)))
  866.     (goto-char (point-max))
  867.     (insert string)))
  868.  
  869. (defun gdb-clear-partial-output (instance)
  870.   (save-excursion
  871.     (set-buffer
  872.      (gdb-get-create-instance-buffer
  873.       instance 'gdb-partial-output-buffer))
  874.     (delete-region (point-min) (point-max))))
  875.  
  876. (defun gdb-append-to-inferior-io (instance string)
  877.   (save-excursion
  878.     (set-buffer
  879.      (gdb-get-create-instance-buffer
  880.       instance 'gdb-inferior-io))
  881.     (goto-char (point-max))
  882.     (insert-before-markers string))
  883.   (gud-display-buffer
  884.    (gdb-get-create-instance-buffer instance
  885.                    'gdb-inferior-io)))
  886.  
  887. (defun gdb-clear-inferior-io (instance)
  888.   (save-excursion
  889.     (set-buffer
  890.      (gdb-get-create-instance-buffer
  891.       instance 'gdb-inferior-io))
  892.     (delete-region (point-min) (point-max))))
  893.  
  894.  
  895.  
  896. ;; One trick is to have a command who's output is always available in
  897. ;; a buffer of it's own, and is always up to date.  We build several 
  898. ;; buffers of this type.
  899. ;;
  900. ;; There are two aspects to this: gdb has to tell us when the output
  901. ;; for that command might have changed, and we have to be able to run
  902. ;; the command behind the user's back.
  903. ;;
  904. ;; The idle input queue and the output phasing associated with 
  905. ;; the instance variable `(gdb-instance-output-sink instance)' help
  906. ;; us to run commands behind the user's back.
  907. ;; 
  908. ;; Below is the code for specificly managing buffers of output from one 
  909. ;; command.
  910. ;;
  911.  
  912.  
  913. ;; The trigger function is suitable for use in the assoc GDB-ANNOTATION-RULES
  914. ;; It adds an idle input for the command we are tracking.  It should be the
  915. ;; annotation rule binding of whatever gdb sends to tell us this command
  916. ;; might have changed it's output.
  917. ;;
  918. ;; NAME is the fucntion name.  DEMAND-PREDICATE tests if output is really needed.
  919. ;; GDB-COMMAND is a string of such.  OUTPUT-HANDLER is the function bound to the
  920. ;; input in the input queue (see comment about ``gdb communications'' above).
  921. (defmacro def-gdb-auto-update-trigger (name demand-predicate gdb-command output-handler)
  922.   (`
  923.    (defun (, name) (instance &optional ignored)
  924.      (if (and ((, demand-predicate) instance)
  925.           (not (member '(, name)
  926.                (gdb-instance-pending-triggers instance))))
  927.      (progn
  928.        (gdb-instance-enqueue-idle-input
  929.         instance
  930.         (list (, gdb-command) '(, output-handler)))
  931.        (set-gdb-instance-pending-triggers
  932.         instance
  933.         (cons '(, name)
  934.           (gdb-instance-pending-triggers instance)))) ))))
  935.         
  936. (defmacro def-gdb-auto-update-handler (name trigger buf-key)
  937.   (`
  938.    (defun (, name) ()
  939.      (set-gdb-instance-pending-triggers
  940.       instance
  941.       (delq '(, trigger)
  942.         (gdb-instance-pending-triggers instance)))
  943.      (let ((buf (gdb-get-instance-buffer instance
  944.                       '(, buf-key))))
  945.        (and buf
  946.         (save-excursion
  947.           (set-buffer buf)
  948.           (buffer-disable-undo buf) ; don't need undo
  949.           (let ((p (point))
  950.             (buffer-read-only nil)
  951.             (instance-buf (gdb-get-create-instance-buffer
  952.                    instance
  953.                    'gdb-partial-output-buffer)))
  954.         (if (gud-buffers-differ buf instance-buf)
  955.             (progn
  956.               (delete-region (point-min) (point-max))
  957.               (insert-buffer instance-buf)
  958.               (if (buffer-dedicated-frame)
  959.               (fit-frame-to-buffer (buffer-dedicated-frame) buf))
  960.               ))
  961.         (goto-char p))))))))
  962.  
  963. (defmacro def-gdb-auto-updated-buffer
  964.   (buffer-key trigger-name gdb-command output-handler-name)
  965.   (`
  966.    (progn
  967.      (def-gdb-auto-update-trigger (, trigger-name)
  968.        ;; The demand predicate:
  969.        (lambda (instance)
  970.      (gdb-get-instance-buffer instance '(, buffer-key)))
  971.        (, gdb-command)
  972.        (, output-handler-name))
  973.      (def-gdb-auto-update-handler (, output-handler-name)
  974.        (, trigger-name) (, buffer-key)))))
  975.  
  976.  
  977. ;;
  978. ;; Breakpoint buffers
  979. ;; 
  980. ;; These display the output of `info breakpoints'.
  981. ;;
  982.  
  983.        
  984. (gdb-set-instance-buffer-rules 'gdb-breakpoints-buffer
  985.                    'gdb-breakpoints-buffer-name
  986.                    'gud-breakpoints-mode)
  987.  
  988. (def-gdb-auto-updated-buffer gdb-breakpoints-buffer
  989.   ;; This defines the auto update rule for buffers of type
  990.   ;; `gdb-breakpoints-buffer'.
  991.   ;;
  992.   ;; It defines a function to serve as the annotation handler that
  993.   ;; handles the `foo-invalidated' message.  That function is called:
  994.   gdb-invalidate-breakpoints
  995.  
  996.   ;; To update the buffer, this command is sent to gdb.
  997.   "server info breakpoints\n"
  998.  
  999.   ;; This also defines a function to be the handler for the output
  1000.   ;; from the command above.  That function will copy the output into
  1001.   ;; the appropriately typed buffer.  That function will be called:
  1002.   gdb-info-breakpoints-handler)
  1003.  
  1004. (defun gdb-breakpoints-buffer-name (instance)
  1005.   (save-excursion
  1006.     (set-buffer (process-buffer (gdb-instance-process instance)))
  1007.     (concat "*breakpoints of " (gdb-instance-target-string instance) "*")))
  1008.  
  1009. (defun gud-display-breakpoints-buffer (instance)
  1010.   (interactive (list (gdb-needed-default-instance)))
  1011.   (gud-display-buffer
  1012.    (gdb-get-create-instance-buffer instance
  1013.                     'gdb-breakpoints-buffer)))
  1014.  
  1015. (defun gud-frame-breakpoints-buffer (instance)
  1016.   (interactive (list (gdb-needed-default-instance)))
  1017.   (gud-display-buffer-new-frame
  1018.    (gdb-get-create-instance-buffer instance
  1019.                     'gdb-breakpoints-buffer)))
  1020.  
  1021. (defvar gud-breakpoints-mode-map nil)
  1022. (defvar gud-breakpoints-mode-menu
  1023.   '("GDB Breakpoint Commands"
  1024.     "----"
  1025.     ["Toggle"         gud-toggle-bp-this-line t]
  1026.     ["Delete"         gud-delete-bp-this-line t]
  1027.     ["Condition"    gud-bp-condition t]
  1028.     ["Ignore"        gud-bp-ignore t])
  1029.   "*menu for gud-breakpoints-mode")
  1030.  
  1031. (setq gud-breakpoints-mode-map (make-keymap))
  1032. (suppress-keymap gud-breakpoints-mode-map)
  1033. (define-key gud-breakpoints-mode-map " " 'gud-toggle-bp-this-line)
  1034. (define-key gud-breakpoints-mode-map "d" 'gud-delete-bp-this-line)
  1035. (define-key gud-breakpoints-mode-map "c" 'gud-bp-condition)
  1036. (define-key gud-breakpoints-mode-map "i" 'gud-bp-ignore)
  1037. (define-key gud-breakpoints-mode-map 'button3 'gud-breakpoints-popup-menu)
  1038. (defun gud-breakpoints-mode ()
  1039.   "Major mode for gud breakpoints.
  1040.  
  1041. \\{gud-breakpoints-mode-map}"
  1042.   (setq major-mode 'gud-breakpoints-mode)
  1043.   (setq mode-name "Breakpoints")
  1044.   (use-local-map gud-breakpoints-mode-map)
  1045.   (setq buffer-read-only t)
  1046.   (require 'mode-motion)
  1047.   (setq mode-motion-hook 'gud-breakpoints-mode-motion-hook)
  1048.   (gdb-invalidate-breakpoints gdb-buffer-instance))
  1049.  
  1050. (defun gud-toggle-bp-this-line ()
  1051.   (interactive)
  1052.   (save-excursion
  1053.     (set-buffer 
  1054.      (gdb-get-instance-buffer gdb-buffer-instance 'gdb-breakpoints-buffer))
  1055.     (if (key-press-event-p last-input-event)
  1056.     (beginning-of-line 1)
  1057.       (and mode-motion-extent (extent-buffer mode-motion-extent)
  1058.        (goto-char (extent-start-position mode-motion-extent))))
  1059.     (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)"))
  1060.     (error "Not recognized as breakpoint line (demo foo).")
  1061.       (gdb-instance-enqueue-idle-input
  1062.        gdb-buffer-instance
  1063.        (list
  1064.     (concat
  1065.      (if (eq ?y (char-after (match-beginning 2)))
  1066.          "server disable "
  1067.        "server enable ")
  1068.      (buffer-substring (match-beginning 0)
  1069.                (match-end 1))
  1070.      "\n")
  1071.     '(lambda () nil)))
  1072.       )))
  1073.  
  1074. (defun gud-delete-bp-this-line ()
  1075.   (interactive)
  1076.   (save-excursion
  1077.     (set-buffer 
  1078.      (gdb-get-instance-buffer gdb-buffer-instance 'gdb-breakpoints-buffer))
  1079.     (if (key-press-event-p last-input-event)
  1080.     (beginning-of-line 1)
  1081.       (and mode-motion-extent (extent-buffer mode-motion-extent)
  1082.        (goto-char (extent-start-position mode-motion-extent))))
  1083.     (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)"))
  1084.     (error "Not recognized as breakpoint line (demo foo).")
  1085.       (gdb-instance-enqueue-idle-input
  1086.        gdb-buffer-instance
  1087.        (list
  1088.     (concat
  1089.      "server delete "
  1090.      (buffer-substring (match-beginning 0)
  1091.                (match-end 1))
  1092.      "\n")
  1093.     '(lambda () nil)))
  1094.       )))
  1095.  
  1096. (defun gud-bp-condition (condition)
  1097.   (interactive "sCondition for breakpoint: ")
  1098.   (save-excursion
  1099.     (set-buffer 
  1100.      (gdb-get-instance-buffer gdb-buffer-instance 'gdb-breakpoints-buffer))
  1101.     (if (key-press-event-p last-input-event)
  1102.     (beginning-of-line 1)
  1103.       (and mode-motion-extent (extent-buffer mode-motion-extent)
  1104.        (goto-char (extent-start-position mode-motion-extent))))
  1105.     (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)"))
  1106.     (error "Not recognized as breakpoint line (demo foo).")
  1107.       (gdb-instance-enqueue-idle-input
  1108.        gdb-buffer-instance
  1109.        (list
  1110.     (concat
  1111.      "server condition "
  1112.      (buffer-substring (match-beginning 0)
  1113.                (match-end 1))
  1114.      (if (> (length condition) 0) (concat " " condition) "")
  1115.      "\n")
  1116.     '(lambda () nil)))
  1117.       (gdb-invalidate-breakpoints gdb-buffer-instance)
  1118.       )))
  1119.  
  1120. (defun gud-bp-ignore (count)
  1121.   (interactive "nNumber of times to ignore breakpoint: ")
  1122.   (save-excursion
  1123.     (set-buffer 
  1124.      (gdb-get-instance-buffer gdb-buffer-instance 'gdb-breakpoints-buffer))
  1125.     (if (key-press-event-p last-input-event)
  1126.     (beginning-of-line 1)
  1127.       (and mode-motion-extent (extent-buffer mode-motion-extent)
  1128.        (goto-char (extent-start-position mode-motion-extent))))
  1129.     (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)"))
  1130.     (error "Not recognized as breakpoint line (demo foo).")
  1131.       (gdb-instance-enqueue-idle-input
  1132.        gdb-buffer-instance
  1133.        (list
  1134.     (concat
  1135.      "server ignore "
  1136.      (buffer-substring (match-beginning 0)
  1137.                (match-end 1))
  1138.      " "
  1139.      (int-to-string count)
  1140.      "\n")
  1141.     '(lambda () nil)))
  1142.       (gdb-invalidate-breakpoints gdb-buffer-instance)
  1143.       )))
  1144.  
  1145. (defun gud-breakpoints-mode-motion-hook (event)
  1146.   (gud-breakpoints-mode-motion-internal event "^[0-9]+[ \t]"))
  1147.  
  1148. (defun gud-breakpoints-mode-motion-internal (event regexp)
  1149.   ;;
  1150.   ;; This is mostly ripped off from mode-motion-highlight-internal but
  1151.   ;; we set the extent's face rather than setting it to highlight. That
  1152.   ;; way if we're somewhere in the breakpoint's list of commands or other
  1153.   ;; info we still highlight it.
  1154.   (if (event-buffer event)
  1155.       (let* ((buffer (event-buffer event))
  1156.          point)
  1157.     (save-excursion
  1158.       (set-buffer buffer)
  1159.       (mouse-set-point event)
  1160.       (beginning-of-line)
  1161.       (if (not (looking-at regexp))
  1162.           (re-search-backward regexp (point-min) 't))
  1163.       (setq point (point))
  1164.       (if (looking-at regexp)
  1165.           (end-of-line))
  1166.       (if (and mode-motion-extent (extent-buffer mode-motion-extent))
  1167.           (if (eq point (point))
  1168.           (delete-extent mode-motion-extent)
  1169.         (set-extent-endpoints mode-motion-extent point (point)))
  1170.         (if (eq point (point))
  1171.         nil
  1172.           (setq mode-motion-extent (make-extent point (point)))
  1173.           (set-extent-property mode-motion-extent 'face
  1174.                    (get-face 'highlight)))))
  1175.     )))
  1176.  
  1177. (defun gud-breakpoints-popup-menu (event)
  1178.   (interactive "@e")
  1179.   (mouse-set-point event)
  1180.   (popup-menu gud-breakpoints-mode-menu))
  1181.  
  1182. ;; 
  1183. ;; Display expression buffers
  1184. ;;
  1185. ;; These show the current list of expressions which the debugger
  1186. ;; prints when the inferior stops and their values. Note that there
  1187. ;; isn't a "display-invalid" annotation so we have to a bit more
  1188. ;; work than for the other auto-update buffers
  1189. ;;
  1190.  
  1191. (gdb-set-instance-buffer-rules 'gdb-display-buffer
  1192.                    'gdb-display-buffer-name
  1193.                    'gud-display-mode)
  1194.  
  1195.  
  1196. (def-gdb-auto-updated-buffer gdb-display-buffer
  1197.   ;; This defines the auto update rule for buffers of type
  1198.   ;; `gdb-display-buffer'.
  1199.   ;;
  1200.   ;; It defines a function to serve as the annotation handler that
  1201.   ;; handles the `foo-invalidated' message.  That function is called:
  1202.   gdb-invalidate-display
  1203.  
  1204.   ;; To update the buffer, this command is sent to gdb.
  1205.   "server info display\n"
  1206.  
  1207.   ;; This also defines a function to be the handler for the output
  1208.   ;; from the command above.  That function will copy the output into
  1209.   ;; the appropriately typed buffer.  That function will be called:
  1210.   gdb-info-display-handler)
  1211.  
  1212.  
  1213. ;; Since the displayed expressions buffer is not simply a copy of what gdb
  1214. ;; prints for the "info display" command we need a slightly more complex
  1215. ;; handler for it than the standard one which def-gdb-auto-updated-buffer
  1216. ;; defines.
  1217.  
  1218. (defun gdb-info-display-handler ()
  1219.  
  1220.   (set-gdb-instance-pending-triggers 
  1221.    instance (delq 'gdb-invalidate-display
  1222.           (gdb-instance-pending-triggers instance)))
  1223.  
  1224.   (let ((buf (gdb-get-instance-buffer instance 'gdb-display-buffer)))
  1225.     (and buf
  1226.      (save-excursion
  1227.        (let ((instance-buf (gdb-get-create-instance-buffer
  1228.                 instance 'gdb-partial-output-buffer))
  1229.          expr-alist point expr highlight-expr)
  1230.          (set-buffer instance-buf)
  1231.          (goto-char (point-min))
  1232.          (while 
  1233.          (re-search-forward "^\\([0-9]+\\):   \\([ny] .*$\\)" (point-max) t)
  1234.            (setq expr-alist 
  1235.              (cons
  1236.               (cons (buffer-substring (match-beginning 1) (match-end 1))
  1237.                 (buffer-substring (match-beginning 2) (match-end 2)))
  1238.               expr-alist)))
  1239.          (set-buffer buf)
  1240.          (setq buffer-read-only nil)
  1241.          (if (and mode-motion-extent 
  1242.               (extent-buffer mode-motion-extent)
  1243.               (extent-start-position mode-motion-extent))
  1244.          (progn
  1245.            (goto-char (extent-start-position mode-motion-extent))
  1246.            (if (looking-at "^[0-9]+:")
  1247.                (setq highlight-expr (buffer-substring (match-beginning 0) (match-end 0))))))
  1248.          (goto-char (point-min))
  1249.          (delete-region (point-min)
  1250.                 (if (not (re-search-forward "^\\([0-9]+\\): " (point-max) t))
  1251.                 (point-max)
  1252.                   (beginning-of-line)
  1253.                   (point)))
  1254.          (if (not expr-alist)
  1255.          (progn
  1256.            (insert "There are no auto-display expressions now.\n")
  1257.            (delete-region (point) (point-max)))
  1258.            (insert "Auto-display expressions now in effect:
  1259. Num Enb Expression = value\n")
  1260.            (while 
  1261.            (re-search-forward "^\\([0-9]+\\):   \\([ny]\\)" (point-max) t)
  1262.          (if (setq expr (assoc (buffer-substring (match-beginning 1) (match-end 1))
  1263.                        expr-alist))
  1264.              (progn 
  1265.                (if (string-equal (substring (cdr expr) 0 1) "y")
  1266.                (replace-match "\\1:   y")
  1267.              (replace-match (format "\\1:   %s" (cdr expr)))
  1268.              (setq point (point))
  1269.              (if (re-search-forward "^[0-9]+: " (point-max) 'move)
  1270.                  (beginning-of-line))
  1271.              (delete-region point (if (eobp) (point) (1- (point)))))
  1272.                (setq expr-alist (delq expr expr-alist)))
  1273.            (beginning-of-line)
  1274.            (setq point (point))
  1275.            (if (re-search-forward "^[0-9]+: " (point-max) 'move 2)
  1276.                (beginning-of-line))
  1277.            (delete-region point (point))))
  1278.            (goto-char (point-max))
  1279.            (while expr-alist
  1280.          (insert (concat (car (car expr-alist)) ":   "
  1281.                  (cdr (car expr-alist)) "\n" ))
  1282.          (setq expr-alist (cdr expr-alist))) )
  1283.          (goto-char (point-min))
  1284.          (if (and mode-motion-extent
  1285.               (extent-buffer mode-motion-extent)
  1286.               highlight-expr
  1287.               (re-search-forward (concat "^" highlight-expr ".*$")  (point-max) t))
  1288.          (set-extent-endpoints mode-motion-extent (match-beginning 0) (match-end 0)))
  1289.          (setq buffer-read-only t)
  1290.          (if (buffer-dedicated-frame)
  1291.          (fit-frame-to-buffer (buffer-dedicated-frame) buf))
  1292.          )))))
  1293.  
  1294. (defvar gud-display-mode-map nil)
  1295. (setq gud-display-mode-map (make-keymap))
  1296. (suppress-keymap gud-display-mode-map)
  1297.  
  1298. (defvar gud-display-mode-menu
  1299.   '("GDB Display Commands"
  1300.     "----"
  1301.     ["Toggle enable"    gud-toggle-disp-this-line t]
  1302.     ["Delete"         gud-delete-disp-this-line t])
  1303.   "*menu for gud-display-mode")
  1304.  
  1305. (define-key gud-display-mode-map " " 'gud-toggle-disp-this-line)
  1306. (define-key gud-display-mode-map "d" 'gud-delete-disp-this-line)
  1307. (define-key gud-display-mode-map 'button3 'gud-display-popup-menu)
  1308.  
  1309. (defun gud-display-mode ()
  1310.   "Major mode for gud display.
  1311.  
  1312. \\{gud-display-mode-map}"
  1313.   (setq major-mode 'gud-display-mode)
  1314.   (setq mode-name "Display")
  1315.   (setq buffer-read-only t)
  1316.   (use-local-map gud-display-mode-map)
  1317.   (require 'mode-motion)
  1318.   (setq mode-motion-hook 'gud-display-mode-motion-hook)
  1319.   (gdb-invalidate-display gdb-buffer-instance)
  1320.   )
  1321.  
  1322. (defun gdb-display-buffer-name (instance)
  1323.   (save-excursion
  1324.     (set-buffer (process-buffer (gdb-instance-process instance)))
  1325.     (concat "*Displayed expressions of " (gdb-instance-target-string instance) "*")))
  1326.  
  1327. (defun gud-display-display-buffer (instance)
  1328.   (interactive (list (gdb-needed-default-instance)))
  1329.   (let ((buf (gdb-get-create-instance-buffer instance
  1330.                          'gdb-display-buffer)))
  1331.     (gdb-invalidate-display instance)
  1332.     (gud-display-buffer buf)))
  1333.  
  1334.  
  1335. (defun gud-frame-display-buffer (instance)
  1336.   (interactive (list (gdb-needed-default-instance)))
  1337.   (let ((buf (gdb-get-create-instance-buffer instance
  1338.                          'gdb-display-buffer)))
  1339.     (gdb-invalidate-display instance)
  1340.     (gud-display-buffer-new-frame buf)))
  1341.  
  1342. (defun gud-toggle-disp-this-line ()
  1343.   (interactive)
  1344.   (save-excursion
  1345.     (set-buffer 
  1346.      (gdb-get-instance-buffer gdb-buffer-instance 'gdb-display-buffer))
  1347.     (if (key-press-event-p last-input-event)
  1348.     (beginning-of-line 1)
  1349.       (and mode-motion-extent (extent-buffer mode-motion-extent)
  1350.        (goto-char (extent-start-position mode-motion-extent))))
  1351.     (if (not (looking-at "\\([0-9]+\\):   \\([ny]\\)"))
  1352.     (error "No expression on this line.")
  1353.       (gdb-instance-enqueue-idle-input
  1354.        gdb-buffer-instance
  1355.        (list
  1356.     (concat
  1357.      (if (eq ?y (char-after (match-beginning 2)))
  1358.          "server disable display "
  1359.        "server enable display ")
  1360.      (buffer-substring (match-beginning 0)
  1361.                (match-end 1))
  1362.      "\n")
  1363.     '(lambda () nil)))
  1364.       )))
  1365.  
  1366. (defun gud-delete-disp-this-line ()
  1367.   (interactive)
  1368.   (save-excursion
  1369.     (set-buffer 
  1370.      (gdb-get-instance-buffer gdb-buffer-instance 'gdb-display-buffer))
  1371.     (if (key-press-event-p last-input-event)
  1372.     (beginning-of-line 1)
  1373.       (and mode-motion-extent (extent-buffer mode-motion-extent)
  1374.        (goto-char (extent-start-position mode-motion-extent))))
  1375.     (if (not (looking-at "\\([0-9]+\\):   \\([ny]\\)"))
  1376.     (error "No expression on this line.")
  1377.       (gdb-instance-enqueue-idle-input
  1378.        gdb-buffer-instance
  1379.        (list
  1380.     (concat
  1381.      "server delete display "
  1382.      (buffer-substring (match-beginning 0)
  1383.                (match-end 1))
  1384.      "\n")
  1385.     '(lambda () nil)))
  1386.       )))
  1387.  
  1388. (defun gud-display-mode-motion-hook (event)
  1389.   (gud-breakpoints-mode-motion-internal event "^[0-9]+: "))
  1390.  
  1391. (defun gud-display-popup-menu (event)
  1392.   (interactive "@e")
  1393.   (mouse-set-point event)
  1394.   (popup-menu gud-display-mode-menu))
  1395.  
  1396. ;; If we get an error whilst evaluating one of the expressions
  1397. ;; we won't get the display-end annotation. Set the sink back to
  1398. ;; user to make sure that the error message is seen
  1399.  
  1400. (defun gdb-error-begin (instance ignored)
  1401.   (set-gdb-instance-output-sink instance 'user))
  1402.  
  1403. (defun gdb-display-begin (instance ignored)
  1404.   (if (gdb-get-instance-buffer instance 'gdb-display-buffer)
  1405.       (progn
  1406.     (set-gdb-instance-output-sink instance 'emacs)
  1407.     (gdb-clear-partial-output instance))
  1408.     (set-gdb-instance-output-sink instance 'user))
  1409.   )
  1410.  
  1411. (defun gdb-display-end (instance ignored)
  1412.   (save-excursion
  1413.     (let ((display-output (gdb-get-instance-buffer instance 'gdb-display-buffer))
  1414.       display-index
  1415.       display-value
  1416.       highlight-expr)
  1417.       (if display-output
  1418.       (progn
  1419.         (set-buffer (gdb-get-instance-buffer 
  1420.              instance 'gdb-partial-output-buffer))
  1421.         (goto-char (point-min))
  1422.         (looking-at "\\([0-9]+\\): ")
  1423.         (setq display-index (buffer-substring (match-beginning 1)
  1424.                           (match-end 1)))
  1425.         (setq display-value (+ 2 (match-end 1)))
  1426.         (set-buffer display-output)
  1427.         (if (and mode-motion-extent 
  1428.              (extent-buffer mode-motion-extent)
  1429.              (extent-start-position mode-motion-extent))
  1430.         (progn
  1431.           (goto-char (extent-start-position mode-motion-extent))
  1432.           (if (looking-at "^[0-9]+:")
  1433.               (setq highlight-expr (buffer-substring (match-beginning 0) (match-end 0))))))
  1434.         (setq buffer-read-only nil)
  1435.         (goto-char (point-min))
  1436.         (if (not (re-search-forward (concat "^" display-index ":   [ny]  ")
  1437.                     (point-max) 'move))
  1438.         (insert (format "%s:   y  " display-index))
  1439.           (goto-char (match-end 0))
  1440.           (if (save-match-data 
  1441.             (re-search-forward "^[0-9]+: " (point-max) 'move))
  1442.           (beginning-of-line))
  1443.           (delete-region (match-end 0) (point)))
  1444.         (insert-buffer-substring (gdb-get-instance-buffer 
  1445.                       instance 'gdb-partial-output-buffer)
  1446.                      display-value)
  1447.         (goto-char (point-min))
  1448.         (if (and mode-motion-extent
  1449.              (extent-buffer mode-motion-extent)
  1450.              highlight-expr
  1451.              (re-search-forward (concat "^" highlight-expr ".*$")  (point-max) t))
  1452.         (set-extent-endpoints mode-motion-extent (match-beginning 0) (match-end 0)))
  1453.         (setq buffer-read-only t)
  1454.         )))
  1455.     (gdb-clear-partial-output instance)
  1456.     (set-gdb-instance-output-sink instance 'user)
  1457.     ))
  1458.  
  1459.  
  1460. ;;
  1461. ;; Frames buffers.  These display a perpetually correct bactracktrace
  1462. ;; (from the command `where').
  1463. ;;
  1464. ;; Alas, if your stack is deep, they are costly.
  1465. ;;
  1466.  
  1467. (gdb-set-instance-buffer-rules 'gdb-stack-buffer
  1468.                    'gdb-stack-buffer-name
  1469.                    'gud-frames-mode)
  1470.  
  1471. (def-gdb-auto-updated-buffer gdb-stack-buffer
  1472.   gdb-invalidate-frames
  1473.   "server where\n"
  1474.   gdb-info-frames-handler)
  1475.  
  1476. (defun gdb-stack-buffer-name (instance)
  1477.   (save-excursion
  1478.     (set-buffer (process-buffer (gdb-instance-process instance)))
  1479.     (concat "*stack frames of "
  1480.         (gdb-instance-target-string instance) "*")))
  1481.  
  1482. (defun gud-display-stack-buffer (instance)
  1483.   (interactive (list (gdb-needed-default-instance)))
  1484.   (gud-display-buffer
  1485.    (gdb-get-create-instance-buffer instance
  1486.                     'gdb-stack-buffer)))
  1487.  
  1488. (defun gud-frame-stack-buffer (instance)
  1489.   (interactive (list (gdb-needed-default-instance)))
  1490.   (gud-display-buffer-new-frame
  1491.    (gdb-get-create-instance-buffer instance
  1492.                     'gdb-stack-buffer)))
  1493.  
  1494. (defvar gud-frames-mode-map nil)
  1495. (setq gud-frames-mode-map (make-keymap))
  1496. (suppress-keymap gud-frames-mode-map)
  1497.  
  1498. ;;; XEmacs change
  1499. ;(define-key gud-frames-mode-map [mouse-2]
  1500. ;  'gud-frames-select-by-mouse)
  1501.  
  1502. (define-key gud-frames-mode-map [button2]
  1503.   'gud-frames-select-by-mouse)
  1504.  
  1505.  
  1506. (defun gud-frames-mode ()
  1507.   "Major mode for gud frames.
  1508.  
  1509. \\{gud-frames-mode-map}"
  1510.   (setq major-mode 'gud-frames-mode)
  1511.   (setq mode-name "Frames")
  1512.   (setq buffer-read-only t)
  1513.   (use-local-map gud-frames-mode-map)
  1514.   (gdb-invalidate-frames gdb-buffer-instance))
  1515.  
  1516. (defun gud-get-frame-number ()
  1517.   (save-excursion
  1518.     (let* ((pos (re-search-backward "^#\\([0-9]*\\)" nil t))
  1519.        (n (or (and pos
  1520.                (string-to-int
  1521.             (buffer-substring (match-beginning 1)
  1522.                       (match-end 1))))
  1523.           0)))
  1524.       n)))
  1525.  
  1526. (defun gud-frames-select-by-mouse (e)
  1527.   (interactive "e")
  1528.   (let (selection)
  1529.     (save-excursion
  1530.       (set-buffer (window-buffer (posn-window (event-end e))))
  1531.       (save-excursion
  1532.     (goto-char (posn-point (event-end e)))
  1533.     (setq selection (gud-get-frame-number))))
  1534.     (select-window (posn-window (event-end e)))
  1535.     (save-excursion
  1536.       (set-buffer (gdb-get-instance-buffer (gdb-needed-default-instance) 'gud))
  1537.       (gud-call "fr %p" selection)
  1538.       (gud-display-frame))))
  1539.  
  1540.  
  1541. ;;
  1542. ;; Registers buffers
  1543. ;;
  1544.  
  1545. (def-gdb-auto-updated-buffer gdb-registers-buffer
  1546.   gdb-invalidate-registers
  1547.   "server info registers\n"
  1548.   gdb-info-registers-handler)
  1549.  
  1550. (gdb-set-instance-buffer-rules 'gdb-registers-buffer
  1551.                    'gdb-registers-buffer-name
  1552.                    'gud-registers-mode)
  1553.  
  1554. (defvar gud-registers-mode-map nil)
  1555. (setq gud-registers-mode-map (make-keymap))
  1556. (suppress-keymap gud-registers-mode-map)
  1557.  
  1558. (defun gud-registers-mode ()
  1559.   "Major mode for gud registers.
  1560.  
  1561. \\{gud-registers-mode-map}"
  1562.   (setq major-mode 'gud-registers-mode)
  1563.   (setq mode-name "Registers")
  1564.   (setq buffer-read-only t)
  1565.   (use-local-map gud-registers-mode-map)
  1566.   (gdb-invalidate-registers gdb-buffer-instance))
  1567.  
  1568. (defun gdb-registers-buffer-name (instance)
  1569.   (save-excursion
  1570.     (set-buffer (process-buffer (gdb-instance-process instance)))
  1571.     (concat "*registers of " (gdb-instance-target-string instance) "*")))
  1572.  
  1573. (defun gud-display-registers-buffer (instance)
  1574.   (interactive (list (gdb-needed-default-instance)))
  1575.   (gud-display-buffer
  1576.    (gdb-get-create-instance-buffer instance
  1577.                     'gdb-registers-buffer)))
  1578.  
  1579. (defun gud-frame-registers-buffer (instance)
  1580.   (interactive (list (gdb-needed-default-instance)))
  1581.   (gud-display-buffer-new-frame
  1582.    (gdb-get-create-instance-buffer instance
  1583.                     'gdb-registers-buffer)))
  1584.  
  1585. ;;
  1586. ;; Locals buffers
  1587. ;;
  1588.  
  1589. (def-gdb-auto-updated-buffer gdb-locals-buffer
  1590.   gdb-invalidate-locals
  1591.   "server info locals\n"
  1592.   gdb-info-locals-handler)
  1593.  
  1594. (gdb-set-instance-buffer-rules 'gdb-locals-buffer
  1595.                    'gdb-locals-buffer-name
  1596.                    'gud-locals-mode)
  1597.  
  1598. (defvar gud-locals-mode-map nil)
  1599. (setq gud-locals-mode-map (make-keymap))
  1600. (suppress-keymap gud-locals-mode-map)
  1601.  
  1602. (defun gud-locals-mode ()
  1603.   "Major mode for gud locals.
  1604.  
  1605. \\{gud-locals-mode-map}"
  1606.   (setq major-mode 'gud-locals-mode)
  1607.   (setq mode-name "Locals")
  1608.   (setq buffer-read-only t)
  1609.   (use-local-map gud-locals-mode-map)
  1610.   (gdb-invalidate-locals gdb-buffer-instance))
  1611.  
  1612. (defun gdb-locals-buffer-name (instance)
  1613.   (save-excursion
  1614.     (set-buffer (process-buffer (gdb-instance-process instance)))
  1615.     (concat "*locals of " (gdb-instance-target-string instance) "*")))
  1616.  
  1617. (defun gud-display-locals-buffer (instance)
  1618.   (interactive (list (gdb-needed-default-instance)))
  1619.   (gud-display-buffer
  1620.    (gdb-get-create-instance-buffer instance
  1621.                     'gdb-locals-buffer)))
  1622.  
  1623. (defun gud-frame-locals-buffer (instance)
  1624.   (interactive (list (gdb-needed-default-instance)))
  1625.   (gud-display-buffer-new-frame
  1626.    (gdb-get-create-instance-buffer instance
  1627.                     'gdb-locals-buffer)))
  1628.  
  1629.  
  1630. ;;;;
  1631. ;;;; Put a friendly face on the GDB on-line help.
  1632. ;;;;
  1633.  
  1634. ;; Keymap for extents in the help buffer
  1635. (setq gdb-help-extent-map (make-keymap))
  1636. (suppress-keymap gdb-help-extent-map)
  1637. (define-key gdb-help-extent-map 'button2 'gdb-help-xref)
  1638. (define-key gdb-help-extent-map 'button3 'gdb-help-popup-menu)
  1639.  
  1640. ;; Keymap for elsewhere in the help buffer
  1641. (setq gdb-help-map (make-keymap))
  1642. (define-key gdb-help-map 'button3 'gdb-help-popup-menu)
  1643.  
  1644. (defvar gud-help-menu
  1645.   '("GDB Help Topics"
  1646.     "----"
  1647.     ("Classes of GDB Commands"
  1648.      "----"
  1649.      ["running" (gdb-help "running") t]
  1650.      ["stack" (gdb-help "stack") t]
  1651.      ["data" (gdb-help "data") t]
  1652.      ["breakpoints" (gdb-help "breakpoints") t]
  1653.      ["files" (gdb-help "files") t]
  1654.      ["status" (gdb-help "status") t]
  1655.      ["support" (gdb-help "support") t]
  1656.      ["user-defined" (gdb-help "user-defined") t]
  1657.      ["aliases" (gdb-help "aliases") t]
  1658.      ["obscure" (gdb-help "obscure") t]
  1659.      ["internals" (gdb-help "internals") t])
  1660.     "----"
  1661.     ("Prefix Commands"
  1662.      "----"
  1663.      ["info"        (gdb-help "info") t]
  1664.      ["delete"        (gdb-help "delete") t]
  1665.      ["disable"        (gdb-help "disable") t]
  1666.      ["enable"        (gdb-help "enable") t]
  1667.      ["maintenance"    (gdb-help "maintenance") t]
  1668.      ["maintenance info" (gdb-help "maintenance info") t]
  1669.      ["maintenance print" (gdb-help "maintenance print") t]
  1670.      ["show"         (gdb-help "show") t]
  1671.      ["show check"     (gdb-help "show check") t]
  1672.      ["show history"     (gdb-help "show history") t]
  1673.      ["show print"     (gdb-help "show print") t]
  1674.      ["set"         (gdb-help "set") t]    
  1675.      ["set check"    (gdb-help "set check") t]
  1676.      ["set history"    (gdb-help "set history") t]
  1677.      ["set print"    (gdb-help "set print") t]
  1678.      ["thread"         (gdb-help "thread") t]
  1679.      ["thread apply"     (gdb-help "thread apply") t]
  1680.      ["unset"         (gdb-help "unset") t])
  1681. ; Only if you build this into gdb
  1682. ;    ("Duel"
  1683. ;    ["summary"        (gdb-help "duel help") t]
  1684. ;    ["ops"        (gdb-help "duel ops") t]
  1685. ;    ["examples"    (gdb-help "duel examples") t])
  1686.     )
  1687.   "*menu for gdb-help")
  1688.  
  1689. (defun gdb-help-popup-menu (event)
  1690.   (interactive "@e")
  1691.   (mouse-set-point event)
  1692.   (popup-menu gud-help-menu))
  1693.  
  1694. (defun gdb-help-xref (event)
  1695.   (interactive "e")
  1696.   (save-excursion
  1697.     (set-buffer (get-buffer (gettext "*Debugger Help*")))
  1698.     (let ((extent (extent-at (event-point event))))
  1699.       (gdb-help 
  1700.        (or (extent-property extent 'back-to)
  1701.        (buffer-substring (extent-start-position extent) 
  1702.                  (extent-end-position extent)))
  1703.        gdb-help-topic)
  1704.       )))
  1705.  
  1706. (defun gdb-help-info ()
  1707.   (interactive)
  1708.   (require 'info)
  1709.   (Info-goto-node "(gdb)Top"))
  1710.  
  1711. ;; Format the help page. We lightly edit the GDB output to add instructions
  1712. ;; on getting help on listed commands using the mouse rather than typing
  1713. ;; "help" at gdb.
  1714. ;;
  1715. ;; We're not trying to re-produce Info's or w3's navigational and cross
  1716. ;; referencing here but just to put a simple mouse-driven front end over
  1717. ;; GDB's help.
  1718. ;;
  1719. ;; The help buffer *ought* to be in gdb-help-mode but we only ever create
  1720. ;; one buffer so just setting a buffer local keymap should be good enough
  1721. ;; for now.
  1722.  
  1723. (defun gdb-format-help-page nil
  1724.   (save-excursion
  1725.     (display-buffer (set-buffer (get-buffer-create
  1726.                  (gettext "*Debugger Help*"))))
  1727.     (erase-buffer)
  1728.     (map-extents '(lambda (extent) (delete-extent extent) nil))
  1729.     (use-local-map gdb-help-map)
  1730.     (insert-buffer (gdb-get-instance-buffer 
  1731.             instance 'gdb-partial-output-buffer))
  1732.     (goto-char (point-min))
  1733.     (forward-line 1)
  1734.     (while (re-search-forward "\\(^.*\\) -- .*$" (point-max) t)
  1735.       (let ((extent (make-extent (match-beginning 1) (match-end 1))))
  1736.     (set-extent-property extent 'face (find-face 'bold))
  1737.     (set-extent-property extent 'highlight t)
  1738.     (set-extent-property extent 'keymap gdb-help-extent-map)
  1739.     ))
  1740.     ;; We use the message at the end of the help to distinguish between
  1741.     ;; help on a class of commands, help on a prefix command and help
  1742.     ;; on a command.
  1743.     (goto-char (point-min))
  1744.     (cond
  1745.      ((looking-at "List of classes of commands:")
  1746.       ;; It's the list of classes
  1747.       (end-of-line)
  1748.       (insert " Click on a highlighted class to see the list of commands
  1749. in that class.")
  1750.       )
  1751.      ((and (not (looking-at "List of classes of commands:"))
  1752.        (re-search-forward "^Type \"help\" followed by command name" (point-max) t))
  1753.       ;; It's help on a specific class
  1754.       (goto-char (point-min))
  1755.       (insert "Help on ")
  1756.       (downcase-word 1)
  1757.       (end-of-line)
  1758.       (insert " Click on a highlighted command to see the help
  1759. for that command or click ")
  1760.       (setq point (point))
  1761.       (insert "here")
  1762.       (setq extent (make-extent point (point)))
  1763.       (set-extent-property extent 'back-to "")
  1764.       (insert " to see the list of classes of commands.\n")
  1765.       )
  1766.      ((re-search-forward "^Type \"help.*subcommand" (point-max) t)
  1767.       ;; It's a prefix command
  1768.       (goto-char (point-min))
  1769.       (insert (concat "Help on \"" gdb-help-topic "\" - "))
  1770.       (downcase-word 1)
  1771.       (end-of-line)
  1772.       (insert " Click on a highlighted topic to see the help
  1773. for that topic or click ")
  1774.       (setq point (point))
  1775.       (insert "here")
  1776.       (setq extent (make-extent point (point)))
  1777.       (string-match " ?[^ \t]*$" gdb-help-topic)
  1778.       (if (equal "" 
  1779.          (set-extent-property extent 'back-to 
  1780.                       (substring gdb-help-topic 
  1781.                          0 (match-beginning 0))))
  1782.       (insert " to see the list of classes of commands.\n")
  1783.     (insert (concat " to see the help on " (extent-property extent 'back-to ))))
  1784.       )
  1785.      (t
  1786.       ;; Must be an ordinary command
  1787.       (goto-char (point-min))
  1788.       (insert (concat "Help on \"" gdb-help-topic "\" - "))
  1789.       (insert " Click ")
  1790.       (setq point (point))
  1791.       (insert "here")
  1792.       (setq extent (make-extent point (point)))
  1793.       (if (equal ""  (set-extent-property extent 'back-to gdb-previous-help-topic))
  1794.       (insert " to see the list of classes of commands.\n")
  1795.     (insert (concat " to see the help on " (extent-property extent 'back-to ))))
  1796.       )
  1797.      )
  1798.     (and extent
  1799.      (set-extent-property extent 'face (find-face 'bold))
  1800.      (set-extent-property extent 'highlight t)
  1801.      (set-extent-property extent 'keymap gdb-help-extent-map))
  1802.     (setq fill-column 78)
  1803.     (fill-region (point-min) (point))
  1804.     (insert "\n")
  1805.     ))
  1806.  
  1807. (defun gdb-help (topic &optional previous-topic)
  1808.   (interactive "sGdb Help Topic: ")
  1809.   (let ((instance (gdb-needed-default-instance))
  1810.     )
  1811.     (save-excursion
  1812.       (set-buffer (get-buffer-create (gettext "*Debugger Help*")))
  1813.       (make-variable-buffer-local 'gdb-help-topic)
  1814.       (make-variable-buffer-local 'gdb-previous-help-topic)
  1815.       (setq gdb-help-topic topic)
  1816.       (setq gdb-previous-help-topic (or previous-topic "")))
  1817.     (gdb-clear-partial-output instance)
  1818.     (gdb-instance-enqueue-idle-input
  1819.      instance
  1820.      (list
  1821.       (concat
  1822.        "server "
  1823.        (if (string-match "^duel" topic)
  1824.        ""
  1825.      "help ")
  1826.        topic
  1827.        "\n")
  1828.       'gdb-format-help-page))))
  1829.  
  1830. ;;;; Menus and stuff
  1831.  
  1832. (defun gdb-install-menubar ()
  1833.   "Installs the Gdb menu at the menubar."
  1834.  
  1835.   ;; We can't define the menu at load-time because many of the functions
  1836.   ;; that we will call won't be bound then.
  1837.   (defvar gdb-menu
  1838.     '("GDB Commands"
  1839.       "----"
  1840.       ("Help"
  1841.        ["info"                gdb-help-info t]
  1842.        "----"
  1843.        ["running      -- Running the program" (gdb-help "running") t]
  1844.        ["stack        -- Examining the stack" (gdb-help "stack") t]
  1845.        ["data         -- Examining data" (gdb-help "data") t]
  1846.        ["breakpoints  -- Making program stop at certain points" (gdb-help "breakpoints") t]
  1847.        ["files        -- Specifying and examining files" (gdb-help "files") t]
  1848.        ["status       -- Status inquiries" (gdb-help "status") t]
  1849.        ["support      -- Support facilities" (gdb-help "support") t]
  1850.        ["user-defined -- User-defined commands" (gdb-help "user-defined") t]
  1851.        ["aliases      -- Aliases of other commands" (gdb-help "aliases") t]
  1852.        ["obscure      -- Obscure features" (gdb-help "obscure") t]
  1853.        ["internals    -- Maintenance commands" (gdb-help "internals") t]
  1854.        "---"
  1855. ; Only if you build this into gdb
  1856. ;      ["Duel summary"        (gdb-help "duel help") t]
  1857. ;      ["Duel ops"        (gdb-help "duel ops") t]
  1858. ;      ["Duel examples"        (gdb-help "duel examples") t]
  1859.        )
  1860.       "---"
  1861.       ("New window showing"
  1862.        ["Local variables"         gud-display-locals-buffer t]
  1863.        ["Displayed expressions"     gud-display-display-buffer t]
  1864.        ["Breakpoints"             gud-display-breakpoints-buffer t]
  1865.        ["Stack trace"             gud-display-stack-buffer t]
  1866.        ["Machine registers"        gud-display-registers-buffer t]
  1867.        )
  1868.       ("New frame showing"
  1869.        ["Local variables"         gud-frame-locals-buffer t]
  1870.        ["Displayed expressions"     gud-frame-display-buffer t]
  1871.        ["Breakpoints"             gud-frame-breakpoints-buffer t]
  1872.        ["Stack trace"             gud-frame-stack-buffer t]
  1873.        ["Machine registers"        gud-frame-registers-buffer t]
  1874.        )
  1875.       "----"
  1876.       ["step"         gud-step t]
  1877.       ["next"         gud-next t]
  1878.       ["finish"         gud-finish t]
  1879.       ["continue"        gud-cont t]
  1880.       ["run"         gud-run t]
  1881.       )
  1882.     "*The menu for GDB mode.")
  1883.   (if (and current-menubar (not (assoc "Gdb" current-menubar)))
  1884.       (progn
  1885.     (set-buffer-menubar (copy-sequence current-menubar))
  1886.     (add-menu nil "Gdb" (cdr gdb-menu))))
  1887.   )
  1888. (add-hook 'gdb-mode-hook 'gdb-install-menubar)
  1889.  
  1890.  
  1891. (gdb-set-instance-buffer-rules 'gdb-command-buffer
  1892.                    'gdb-command-buffer-name
  1893.                    'gud-command-mode)
  1894.  
  1895. (defvar gud-command-mode-map nil)
  1896. (setq gud-command-mode-map (make-keymap))
  1897. (suppress-keymap gud-command-mode-map)
  1898. ;;; XEmacs change
  1899. ;(define-key gud-command-mode-map [mouse-2] 'gud-menu-pick)
  1900. (define-key gud-command-mode-map [button2] 'gud-menu-pick)
  1901.  
  1902.  
  1903. (defun gud-command-mode ()
  1904.   "Major mode for gud menu.
  1905.  
  1906. \\{gud-command-mode-map}" (interactive) (setq major-mode 'gud-command-mode)
  1907.   (setq mode-name "Menu") (setq buffer-read-only t) (use-local-map
  1908.   gud-command-mode-map) (make-variable-buffer-local 'gud-menu-position)
  1909.   (if (not gud-menu-position) (gud-goto-menu gud-running-menu)))
  1910.  
  1911. (defun gdb-command-buffer-name (instance)
  1912.   (save-excursion
  1913.     (set-buffer (process-buffer (gdb-instance-process instance)))
  1914.     (concat "*menu of " (gdb-instance-target-string instance) "*")))
  1915.  
  1916. (defun gud-display-command-buffer (instance)
  1917.   (interactive (list (gdb-needed-default-instance)))
  1918.   (gud-display-buffer
  1919.    (gdb-get-create-instance-buffer instance
  1920.                    'gdb-command-buffer)
  1921.    6))
  1922.  
  1923. (defun gud-frame-command-buffer (instance)
  1924.   (interactive (list (gdb-needed-default-instance)))
  1925.   (gud-display-buffer-new-frame
  1926.    (gdb-get-create-instance-buffer instance
  1927.                     'gdb-command-buffer)))
  1928.  
  1929.  
  1930.  
  1931. (defun gdb-call-showing-gud (instance command)
  1932.   (gud-display-gud-buffer instance)
  1933.   (comint-input-sender (gdb-instance-process instance) command))
  1934.  
  1935. (defvar gud-target-history ())
  1936.  
  1937. (defun gud-temp-buffer-show (buf)
  1938.   (let ((ow (selected-window)))
  1939.     (unwind-protect
  1940.     (progn
  1941.       (pop-to-buffer buf)
  1942.  
  1943.       ;; This insertion works around a bug in emacs.
  1944.       ;; The bug is that all the empty space after a
  1945.       ;; highlighted word that terminates a buffer
  1946.       ;; gets highlighted.  That's really ugly, so
  1947.       ;; make sure a highlighted word can't ever
  1948.       ;; terminate the buffer.
  1949.       (goto-char (point-max))
  1950.       (insert "\n")
  1951.       (goto-char (point-min))
  1952.  
  1953.       (if (< (window-height) 10)
  1954.           (enlarge-window (- 10 (window-height)))))
  1955.       (select-window ow))))
  1956.  
  1957. (defun gud-target (instance command)
  1958.   (interactive 
  1959.    (let* ((instance (gdb-needed-default-instance))
  1960.       (temp-buffer-show-function (function gud-temp-buffer-show))
  1961.       (target-name (completing-read (format "Target type: ")
  1962.                     '(("remote")
  1963.                       ("core")
  1964.                       ("child")
  1965.                       ("exec"))
  1966.                     nil
  1967.                     t
  1968.                     nil
  1969.                     'gud-target-history)))
  1970.      (list instance
  1971.        (cond
  1972.         ((equal target-name "child") "run")
  1973.  
  1974.         ((equal target-name "core")
  1975.          (concat "target core "
  1976.              (read-file-name "core file: "
  1977.                      nil
  1978.                      "core"
  1979.                      t)))
  1980.  
  1981.         ((equal target-name "exec")
  1982.          (concat "target exec "
  1983.              (read-file-name "exec file: "
  1984.                      nil
  1985.                      "a.out"
  1986.                      t)))
  1987.  
  1988.         ((equal target-name "remote")
  1989.          (concat "target remote "
  1990.              (read-file-name "serial line for remote: "
  1991.                      "/dev/"
  1992.                      "ttya"
  1993.                      t)))
  1994.  
  1995.         (t "echo No such target command!")))))
  1996.  
  1997.   (gud-display-gud-buffer instance)
  1998.   (apply comint-input-sender
  1999.      (list (gdb-instance-process instance) command)))
  2000.  
  2001. (defun gud-backtrace ()
  2002.   (interactive)
  2003.   (let ((instance  (gdb-needed-default-instance)))
  2004.     (gud-display-gud-buffer instance)
  2005.     (apply comint-input-sender
  2006.        (list (gdb-instance-process instance)
  2007.          "backtrace"))))
  2008.  
  2009. (defun gud-frame ()
  2010.   (interactive)
  2011.   (let ((instance  (gdb-needed-default-instance)))
  2012.     (apply comint-input-sender
  2013.        (list (gdb-instance-process instance)
  2014.          "frame"))))
  2015.  
  2016. (defun gud-return (instance command)
  2017.    (interactive
  2018.     (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2019.       (list (gdb-needed-default-instance)
  2020.         (concat "return " (read-string "Expression to return: ")))))
  2021.    (gud-display-gud-buffer instance)
  2022.    (apply comint-input-sender
  2023.       (list (gdb-instance-process instance) command)))
  2024.  
  2025.  
  2026. (defun gud-file (instance command)
  2027.   (interactive
  2028.    (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2029.      (list (gdb-needed-default-instance)
  2030.        (concat "file " (read-file-name "Executable to debug: "
  2031.                        nil
  2032.                        "a.out"
  2033.                        t)))))
  2034.   (gud-display-gud-buffer instance)
  2035.   (apply comint-input-sender
  2036.      (list (gdb-instance-process instance) command)))
  2037.  
  2038. (defun gud-core-file (instance command)
  2039.   (interactive
  2040.    (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2041.      (list (gdb-needed-default-instance)
  2042.        (concat "core " (read-file-name "Core file to debug: "
  2043.                        nil
  2044.                        "core-file"
  2045.                        t)))))
  2046.   (gud-display-gud-buffer instance)
  2047.   (apply comint-input-sender
  2048.      (list (gdb-instance-process instance) command)))
  2049.  
  2050. (defun gud-cd (dir)
  2051.   (interactive "FChange GDB's default directory: ")
  2052.   (let ((instance (gdb-needed-default-instance)))
  2053.     (save-excursion
  2054.       (set-buffer (gdb-get-instance-buffer instance 'gud))
  2055.       (cd dir))
  2056.     (gud-display-gud-buffer instance)
  2057.     (apply comint-input-sender
  2058.        (list (gdb-instance-process instance)
  2059.          (concat "cd " dir)))))
  2060.  
  2061.  
  2062. (defun gud-exec-file (instance command)
  2063.   (interactive
  2064.    (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2065.      (list (gdb-needed-default-instance)
  2066.        (concat "exec-file " (read-file-name "Init memory from executable: "
  2067.                         nil
  2068.                         "a.out"
  2069.                         t)))))
  2070.   (gud-display-gud-buffer instance)
  2071.   (apply comint-input-sender
  2072.      (list (gdb-instance-process instance) command)))
  2073.  
  2074. (defun gud-load (instance command)
  2075.   (interactive
  2076.    (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2077.      (list (gdb-needed-default-instance)
  2078.        (concat "load " (read-file-name "Dynamicly load from file: "
  2079.                        nil
  2080.                        "a.out"
  2081.                        t)))))
  2082.   (gud-display-gud-buffer instance)
  2083.   (apply comint-input-sender
  2084.      (list (gdb-instance-process instance) command)))
  2085.  
  2086. (defun gud-symbol-file (instance command)
  2087.   (interactive
  2088.    (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2089.      (list (gdb-needed-default-instance)
  2090.        (concat "symbol-file " (read-file-name "Read symbol table from file: "
  2091.                           nil
  2092.                           "a.out"
  2093.                           t)))))
  2094.   (gud-display-gud-buffer instance)
  2095.   (apply comint-input-sender
  2096.      (list (gdb-instance-process instance) command)))
  2097.  
  2098.  
  2099. (defun gud-add-symbol-file (instance command)
  2100.   (interactive
  2101.    (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2102.      (list (gdb-needed-default-instance)
  2103.        (concat "add-symbol-file "
  2104.            (read-file-name "Add symbols from file: "
  2105.                    nil
  2106.                    "a.out"
  2107.                    t)))))
  2108.   (gud-display-gud-buffer instance)
  2109.   (apply comint-input-sender
  2110.      (list (gdb-instance-process instance) command)))
  2111.  
  2112.  
  2113. (defun gud-sharedlibrary (instance command)
  2114.   (interactive
  2115.    (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
  2116.      (list (gdb-needed-default-instance)
  2117.        (concat "sharedlibrary "
  2118.            (read-string "Load symbols for files matching regexp: ")))))
  2119.   (gud-display-gud-buffer instance)
  2120.   (apply comint-input-sender
  2121.      (list (gdb-instance-process instance) command)))
  2122.  
  2123.  
  2124. ;;;; Help
  2125.  
  2126.  
  2127.  
  2128. ;;;; Window management
  2129.  
  2130.  
  2131. ;;; FIXME: This should only return true for buffers in the current instance
  2132. (defun gud-protected-buffer-p (buffer)
  2133.   "Is BUFFER a buffer which we want to leave displayed?"
  2134.   (save-excursion
  2135.     (set-buffer buffer)
  2136.     (or gdb-buffer-type
  2137.     overlay-arrow-position)))
  2138.  
  2139. ;;; The way we abuse the dedicated-p flag is pretty gross, but seems
  2140. ;;; to do the right thing.  Seeing as there is no way for Lisp code to
  2141. ;;; get at the use_time field of a window, I'm not sure there exists a
  2142. ;;; more elegant solution without writing C code.
  2143.  
  2144. (defun gud-display-buffer (buf &optional size)
  2145.   (let ((must-split nil)
  2146.     (answer nil))
  2147.     (save-excursion
  2148.       (unwind-protect
  2149.       (progn
  2150.         (walk-windows
  2151.          '(lambda (win)
  2152.         (if (gud-protected-buffer-p (window-buffer win))
  2153.             (set-window-buffer-dedicated win (window-buffer win)))))
  2154.         (setq answer (get-buffer-window buf))
  2155.         (if (not answer)
  2156.         (let ((window (get-lru-window)))
  2157.           (if (not (window-dedicated-p window))
  2158.               (progn
  2159.             (set-window-buffer window buf)
  2160.             (setq answer window))
  2161.             (setq must-split t)))))
  2162.     (walk-windows
  2163.      '(lambda (win)
  2164.         (if (gud-protected-buffer-p (window-buffer win))
  2165.         (set-window-buffer-dedicated win nil)))))
  2166.       (if must-split
  2167.       (let* ((largest (get-largest-window))
  2168.          (cur-size (window-height largest))
  2169.          (new-size (and size (< size cur-size) (- cur-size size))))
  2170.         (setq answer (split-window largest new-size))
  2171.         (set-window-buffer answer buf)))
  2172.       answer)))
  2173.  
  2174. (defun existing-source-window (buffer)
  2175.   (catch 'found
  2176.     (save-excursion
  2177.       (walk-windows
  2178.        (function
  2179.     (lambda (win)
  2180.       (if (and overlay-arrow-position
  2181.            (eq (window-buffer win)
  2182.                (marker-buffer overlay-arrow-position)))
  2183.           (progn
  2184.         (set-window-buffer win buffer)
  2185.         (throw 'found win))))))
  2186.       nil)))
  2187.       
  2188. (defun gud-display-source-buffer (buffer)
  2189.   (or (existing-source-window buffer)
  2190.       (gud-display-buffer buffer)))
  2191.  
  2192. (defun gud-display-buffer-new-frame (buf)
  2193.   (save-excursion
  2194.     (set-buffer buf)
  2195.     (let* ((buf-height (+ 4 (count-lines (point-min) (point-max))))
  2196.        (frame-params (list (cons 'height buf-height)))
  2197.        )
  2198.       ;; This is a hack so that we can re-size this window to occupy just as
  2199.       ;; much space is needed.
  2200.       (setq truncate-lines t)
  2201.       (set-buffer-dedicated-frame buf (make-frame frame-params)))))
  2202.  
  2203.  
  2204.  
  2205. ;;; Shared keymap initialization:
  2206.  
  2207. (defun gud-display-gud-buffer (instance)
  2208.   (interactive (list (gdb-needed-default-instance)))
  2209.   (gud-display-buffer
  2210.    (gdb-get-create-instance-buffer instance 'gud)))
  2211.  
  2212. (defun gud-frame-gud-buffer (instance)
  2213.   (interactive (list (gdb-needed-default-instance)))
  2214.   (gud-display-buffer-new-frame
  2215.    (gdb-get-create-instance-buffer instance 'gud)))
  2216.  
  2217.  
  2218. (defun gud-gdb-find-file (f)
  2219.   (find-file-noselect f))
  2220.  
  2221. ;;; XEmacs: don't autoload this yet since it's still buggy - use the
  2222. ;;; one in gdb.el instead
  2223. (defun gdb (command-line)
  2224.   "Run gdb on program FILE in buffer *gud-FILE*.
  2225. The directory containing FILE becomes the initial working directory
  2226. and source-file directory for your debugger."
  2227.   (interactive
  2228.    (list (read-shell-command "Run gdb (like this): "
  2229.                    (if (consp gud-gdb-history)
  2230.                    (car gud-gdb-history)
  2231.                  "gdb ")
  2232.                    '(gud-gdb-history . 1))))
  2233.   (gud-overload-functions
  2234.    '((gud-massage-args . gud-gdb-massage-args)
  2235.      (gud-marker-filter . gud-gdb-marker-filter)
  2236.      (gud-find-file . gud-gdb-find-file)
  2237.      ))
  2238.  
  2239.   (let* ((words (gud-chop-words command-line))
  2240.      (program (car words))
  2241.      (file-word (let ((w (cdr words)))
  2242.               (while (and w (= ?- (aref (car w) 0)))
  2243.             (setq w (cdr w)))
  2244.               (car w)))
  2245.      (args (delq file-word (cdr words)))
  2246.      (file (and file-word (expand-file-name file-word)))
  2247.      (filepart (if file (file-name-nondirectory file) ""))
  2248.      (buffer-name (concat "*" "gdb"
  2249.                   (and (string< "" filepart) 
  2250.                    (concat "-" filepart)) "*")))
  2251.     (setq gdb-first-time (not (get-buffer-process buffer-name))))
  2252.  
  2253.   (gud-common-init command-line "gdb")
  2254.  
  2255.   (gud-def gud-break  "break %f:%l"  "\C-b" "Set breakpoint at current line.")
  2256.   (gud-def gud-tbreak "tbreak %f:%l" "\C-t" "Set breakpoint at current line.")
  2257.   (gud-def gud-remove "clear %l"     "\C-d" "Remove breakpoint at current line")
  2258.   (gud-def gud-kill   "kill"         nil    "Kill the program.")
  2259.   (gud-def gud-run    "run"         nil    "Run the program.")
  2260.   (gud-def gud-stepi  "stepi %p"     "\C-i" "Step one instruction with display.")
  2261.   (gud-def gud-step   "step %p"      "\C-s" "Step one source line with display.")
  2262.   (gud-def gud-next   "next %p"      "\C-n" "Step one line (skip functions).")
  2263.   (gud-def gud-finish "finish"       "\C-f" "Finish executing current function.")
  2264.   (gud-def gud-cont   "cont"         "\C-r" "Continue with display.")
  2265.   (gud-def gud-up     "up %p"        "<" "Up N stack frames (numeric arg).")
  2266.   (gud-def gud-down   "down %p"      ">" "Down N stack frames (numeric arg).")
  2267.   (gud-def gud-print  "print %e"     "\C-p" "Evaluate C expression at point.")
  2268.  
  2269.   (setq comint-prompt-regexp "^(.*gdb[+]?) *")
  2270.   (setq comint-input-sender 'gdb-send)
  2271.   (run-hooks 'gdb-mode-hook)
  2272.   (let ((instance
  2273.      (make-gdb-instance (get-buffer-process (current-buffer)))
  2274.      ))
  2275.     (if gdb-first-time (gdb-clear-inferior-io instance)))
  2276.   )
  2277.  
  2278.  
  2279. ;; ======================================================================
  2280. ;; sdb functions
  2281.  
  2282. ;;; History of argument lists passed to sdb.
  2283. (defvar gud-sdb-history nil)
  2284.  
  2285. (defvar gud-sdb-needs-tags (not (file-exists-p "/var"))
  2286.   "If nil, we're on a System V Release 4 and don't need the tags hack.")
  2287.  
  2288. (defvar gud-sdb-lastfile nil)
  2289.  
  2290. (defun gud-sdb-massage-args (file args)
  2291.   (cons file args))
  2292.  
  2293. (defun gud-sdb-marker-filter (string)
  2294.   (cond 
  2295.    ;; System V Release 3.2 uses this format
  2296.    ((string-match "\\(^0x\\w* in \\|^\\|\n\\)\\([^:\n]*\\):\\([0-9]*\\):.*\n"
  2297.             string)
  2298.     (setq gud-last-frame
  2299.       (cons
  2300.        (substring string (match-beginning 2) (match-end 2))
  2301.        (string-to-int 
  2302.         (substring string (match-beginning 3) (match-end 3))))))
  2303.    ;; System V Release 4.0 
  2304.    ((string-match "^\\(BREAKPOINT\\|STEPPED\\) process [0-9]+ function [^ ]+ in \\(.+\\)\n"
  2305.                string)
  2306.     (setq gud-sdb-lastfile
  2307.       (substring string (match-beginning 2) (match-end 2))))
  2308.    ((and gud-sdb-lastfile (string-match "^\\([0-9]+\\):" string))
  2309.      (setq gud-last-frame
  2310.            (cons
  2311.         gud-sdb-lastfile
  2312.         (string-to-int 
  2313.          (substring string (match-beginning 1) (match-end 1))))))
  2314.    (t 
  2315.     (setq gud-sdb-lastfile nil)))
  2316.   string)
  2317.  
  2318. (defun gud-sdb-find-file (f)
  2319.   (if gud-sdb-needs-tags
  2320.       (find-tag-noselect f)
  2321.     (find-file-noselect f)))
  2322.  
  2323. ;;;###autoload
  2324. (defun sdb (command-line)
  2325.   "Run sdb on program FILE in buffer *gud-FILE*.
  2326. The directory containing FILE becomes the initial working directory
  2327. and source-file directory for your debugger."
  2328.   (interactive
  2329.    (list (read-from-minibuffer "Run sdb (like this): "
  2330.                    (if (consp gud-sdb-history)
  2331.                    (car gud-sdb-history)
  2332.                  "sdb ")
  2333.                    nil nil
  2334.                    '(gud-sdb-history . 1))))
  2335.   (if (and gud-sdb-needs-tags
  2336.        (not (and (boundp 'tags-file-name) (file-exists-p tags-file-name))))
  2337.       (error "The sdb support requires a valid tags table to work."))
  2338.   (gud-overload-functions '((gud-massage-args . gud-sdb-massage-args)
  2339.                 (gud-marker-filter . gud-sdb-marker-filter)
  2340.                 (gud-find-file . gud-sdb-find-file)
  2341.                 ))
  2342.  
  2343.   (gud-common-init command-line "sdb")
  2344.  
  2345.   (gud-def gud-break  "%l b" "\C-b"   "Set breakpoint at current line.")
  2346.   (gud-def gud-tbreak "%l c" "\C-t"   "Set temporary breakpoint at current line.")
  2347.   (gud-def gud-remove "%l d" "\C-d"   "Remove breakpoint at current line")
  2348.   (gud-def gud-step   "s %p" "\C-s"   "Step one source line with display.")
  2349.   (gud-def gud-stepi  "i %p" "\C-i"   "Step one instruction with display.")
  2350.   (gud-def gud-next   "S %p" "\C-n"   "Step one line (skip functions).")
  2351.   (gud-def gud-cont   "c"    "\C-r"   "Continue with display.")
  2352.   (gud-def gud-print  "%e/"  "\C-p"   "Evaluate C expression at point.")
  2353.  
  2354.   (setq comint-prompt-regexp  "\\(^\\|\n\\)\\*")
  2355.   (run-hooks 'sdb-mode-hook)
  2356.   )
  2357.  
  2358. ;; ======================================================================
  2359. ;; dbx functions
  2360.  
  2361. ;;; History of argument lists passed to dbx.
  2362. (defvar gud-dbx-history nil)
  2363.  
  2364. (defun gud-dbx-massage-args (file args)
  2365.   (cons file args))
  2366.  
  2367. (defun gud-dbx-marker-filter (string)
  2368.   (if (or (string-match
  2369.          "stopped in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\""
  2370.          string)
  2371.         (string-match
  2372.          "signal .* in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\""
  2373.          string))
  2374.       (setq gud-last-frame
  2375.         (cons
  2376.          (substring string (match-beginning 2) (match-end 2))
  2377.          (string-to-int 
  2378.           (substring string (match-beginning 1) (match-end 1))))))
  2379.   string)
  2380.  
  2381. (defun gud-dbx-find-file (f)
  2382.   (find-file-noselect f))
  2383.  
  2384. ;;;###autoload
  2385. (defun dbx (command-line)
  2386.   "Run dbx on program FILE in buffer *gud-FILE*.
  2387. The directory containing FILE becomes the initial working directory
  2388. and source-file directory for your debugger."
  2389.   (interactive
  2390.    (list (read-from-minibuffer "Run dbx (like this): "
  2391.                    (if (consp gud-dbx-history)
  2392.                    (car gud-dbx-history)
  2393.                  "dbx ")
  2394.                    nil nil
  2395.                    '(gud-dbx-history . 1))))
  2396.   (gud-overload-functions '((gud-massage-args . gud-dbx-massage-args)
  2397.                 (gud-marker-filter . gud-dbx-marker-filter)
  2398.                 (gud-find-file . gud-dbx-find-file)
  2399.                 ))
  2400.  
  2401.   (gud-common-init command-line "dbx")
  2402.  
  2403.   (gud-def gud-break  "file \"%d%f\"\nstop at %l"
  2404.                      "\C-b" "Set breakpoint at current line.")
  2405. ;;  (gud-def gud-break  "stop at \"%f\":%l"
  2406. ;;                     "\C-b" "Set breakpoint at current line.")
  2407.   (gud-def gud-remove "clear %l"  "\C-d" "Remove breakpoint at current line")
  2408.   (gud-def gud-step   "step %p"      "\C-s" "Step one line with display.")
  2409.   (gud-def gud-stepi  "stepi %p"  "\C-i" "Step one instruction with display.")
  2410.   (gud-def gud-next   "next %p"      "\C-n" "Step one line (skip functions).")
  2411.   (gud-def gud-cont   "cont"      "\C-r" "Continue with display.")
  2412.   (gud-def gud-up     "up %p"      "<" "Up (numeric arg) stack frames.")
  2413.   (gud-def gud-down   "down %p"      ">" "Down (numeric arg) stack frames.")
  2414.   (gud-def gud-print  "print %e"  "\C-p" "Evaluate C expression at point.")
  2415.  
  2416.   (setq comint-prompt-regexp  "^[^)]*dbx) *")
  2417.   (run-hooks 'dbx-mode-hook)
  2418.   )
  2419.  
  2420. ;; ======================================================================
  2421. ;; xdb (HP PARISC debugger) functions
  2422.  
  2423. ;;; History of argument lists passed to xdb.
  2424. (defvar gud-xdb-history nil)
  2425.  
  2426. (defvar gud-xdb-directories nil
  2427.   "*A list of directories that xdb should search for source code.
  2428. If nil, only source files in the program directory
  2429. will be known to xdb.
  2430.  
  2431. The file names should be absolute, or relative to the directory
  2432. containing the executable being debugged.")
  2433.  
  2434. (defun gud-xdb-massage-args (file args)
  2435.   (nconc (let ((directories gud-xdb-directories)
  2436.            (result nil))
  2437.        (while directories
  2438.          (setq result (cons (car directories) (cons "-d" result)))
  2439.          (setq directories (cdr directories)))
  2440.        (nreverse (cons file result)))
  2441.      args))
  2442.  
  2443. (defun gud-xdb-file-name (f)
  2444.   "Transform a relative pathname to a full pathname in xdb mode"
  2445.   (let ((result nil))
  2446.     (if (file-exists-p f)
  2447.         (setq result (expand-file-name f))
  2448.       (let ((directories gud-xdb-directories))
  2449.         (while directories
  2450.           (let ((path (concat (car directories) "/" f)))
  2451.             (if (file-exists-p path)
  2452.                 (setq result (expand-file-name path)
  2453.                       directories nil)))
  2454.           (setq directories (cdr directories)))))
  2455.     result))
  2456.  
  2457. ;; xdb does not print the lines all at once, so we have to accumulate them
  2458. (defvar gud-xdb-accumulation "")
  2459.  
  2460. (defun gud-xdb-marker-filter (string)
  2461.   (let (result)
  2462.     (if (or (string-match comint-prompt-regexp string)
  2463.             (string-match ".*\012" string))
  2464.         (setq result (concat gud-xdb-accumulation string)
  2465.               gud-xdb-accumulation "")
  2466.       (setq gud-xdb-accumulation (concat gud-xdb-accumulation string)))
  2467.     (if result
  2468.         (if (or (string-match "\\([^\n \t:]+\\): [^:]+: \\([0-9]+\\):" result)
  2469.                 (string-match "[^: \t]+:[ \t]+\\([^:]+\\): [^:]+: \\([0-9]+\\):"
  2470.                               result))
  2471.             (let ((line (string-to-int 
  2472.                          (substring result (match-beginning 2) (match-end 2))))
  2473.                   (file (gud-xdb-file-name
  2474.                          (substring result (match-beginning 1) (match-end 1)))))
  2475.               (if file
  2476.                   (setq gud-last-frame (cons file line))))))
  2477.     (or result "")))    
  2478.                
  2479. (defun gud-xdb-find-file (f)
  2480.   (let ((realf (gud-xdb-file-name f)))
  2481.     (if realf (find-file-noselect realf))))
  2482.  
  2483. ;;;###autoload
  2484. (defun xdb (command-line)
  2485.   "Run xdb on program FILE in buffer *gud-FILE*.
  2486. The directory containing FILE becomes the initial working directory
  2487. and source-file directory for your debugger.
  2488.  
  2489. You can set the variable 'gud-xdb-directories' to a list of program source
  2490. directories if your program contains sources from more than one directory."
  2491.   (interactive
  2492.    (list (read-from-minibuffer "Run xdb (like this): "
  2493.                    (if (consp gud-xdb-history)
  2494.                    (car gud-xdb-history)
  2495.                  "xdb ")
  2496.                    nil nil
  2497.                    '(gud-xdb-history . 1))))
  2498.   (gud-overload-functions '((gud-massage-args . gud-xdb-massage-args)
  2499.                 (gud-marker-filter . gud-xdb-marker-filter)
  2500.                 (gud-find-file . gud-xdb-find-file)))
  2501.  
  2502.   (gud-common-init command-line "xdb")
  2503.  
  2504.   (gud-def gud-break  "b %f:%l"    "\C-b" "Set breakpoint at current line.")
  2505.   (gud-def gud-tbreak "b %f:%l\\t" "\C-t"
  2506.            "Set temporary breakpoint at current line.")
  2507.   (gud-def gud-remove "db"         "\C-d" "Remove breakpoint at current line")
  2508.   (gud-def gud-step   "s %p"       "\C-s" "Step one line with display.")
  2509.   (gud-def gud-next   "S %p"       "\C-n" "Step one line (skip functions).")
  2510.   (gud-def gud-cont   "c"       "\C-r" "Continue with display.")
  2511.   (gud-def gud-up     "up %p"       "<"    "Up (numeric arg) stack frames.")
  2512.   (gud-def gud-down   "down %p"       ">"    "Down (numeric arg) stack frames.")
  2513.   (gud-def gud-finish "bu\\t"      "\C-f" "Finish executing current function.")
  2514.   (gud-def gud-print  "p %e"       "\C-p" "Evaluate C expression at point.")
  2515.  
  2516.   (setq comint-prompt-regexp  "^>")
  2517.   (make-local-variable 'gud-xdb-accumulation)
  2518.   (setq gud-xdb-accumulation "")
  2519.   (run-hooks 'xdb-mode-hook))
  2520.  
  2521. ;; ======================================================================
  2522. ;; perldb functions
  2523.  
  2524. ;;; History of argument lists passed to perldb.
  2525. (defvar gud-perldb-history nil)
  2526.  
  2527. (defun gud-perldb-massage-args (file args)
  2528.   (cons "-d" (cons file (cons "-emacs" args))))
  2529.  
  2530. ;; There's no guarantee that Emacs will hand the filter the entire
  2531. ;; marker at once; it could be broken up across several strings.  We
  2532. ;; might even receive a big chunk with several markers in it.  If we
  2533. ;; receive a chunk of text which looks like it might contain the
  2534. ;; beginning of a marker, we save it here between calls to the
  2535. ;; filter.
  2536. (defvar gud-perldb-marker-acc "")
  2537.  
  2538. (defun gud-perldb-marker-filter (string)
  2539.   (save-match-data
  2540.     (setq gud-perldb-marker-acc (concat gud-perldb-marker-acc string))
  2541.     (let ((output ""))
  2542.  
  2543.       ;; Process all the complete markers in this chunk.
  2544.       (while (string-match "^\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n"
  2545.                gud-perldb-marker-acc)
  2546.     (setq
  2547.  
  2548.      ;; Extract the frame position from the marker.
  2549.      gud-last-frame
  2550.      (cons (substring gud-perldb-marker-acc (match-beginning 1) (match-end 1))
  2551.            (string-to-int (substring gud-perldb-marker-acc
  2552.                      (match-beginning 2)
  2553.                      (match-end 2))))
  2554.  
  2555.      ;; Append any text before the marker to the output we're going
  2556.      ;; to return - we don't include the marker in this text.
  2557.      output (concat output
  2558.             (substring gud-perldb-marker-acc 0 (match-beginning 0)))
  2559.  
  2560.      ;; Set the accumulator to the remaining text.
  2561.      gud-perldb-marker-acc (substring gud-perldb-marker-acc (match-end 0))))
  2562.  
  2563.       ;; Does the remaining text look like it might end with the
  2564.       ;; beginning of another marker?  If it does, then keep it in
  2565.       ;; gud-perldb-marker-acc until we receive the rest of it.  Since we
  2566.       ;; know the full marker regexp above failed, it's pretty simple to
  2567.       ;; test for marker starts.
  2568.       (if (string-match "^\032.*\\'" gud-perldb-marker-acc)
  2569.       (progn
  2570.         ;; Everything before the potential marker start can be output.
  2571.         (setq output (concat output (substring gud-perldb-marker-acc
  2572.                            0 (match-beginning 0))))
  2573.  
  2574.         ;; Everything after, we save, to combine with later input.
  2575.         (setq gud-perldb-marker-acc
  2576.           (substring gud-perldb-marker-acc (match-beginning 0))))
  2577.  
  2578.     (setq output (concat output gud-perldb-marker-acc)
  2579.           gud-perldb-marker-acc ""))
  2580.  
  2581.       output)))
  2582.  
  2583. (defun gud-perldb-find-file (f)
  2584.   (find-file-noselect f))
  2585.  
  2586. ;;;###autoload
  2587. (defun perldb (command-line)
  2588.   "Run perldb on program FILE in buffer *gud-FILE*.
  2589. The directory containing FILE becomes the initial working directory
  2590. and source-file directory for your debugger."
  2591.   (interactive
  2592.    (list (read-from-minibuffer "Run perldb (like this): "
  2593.                    (if (consp gud-perldb-history)
  2594.                    (car gud-perldb-history)
  2595.                  "perl ")
  2596.                    nil nil
  2597.                    '(gud-perldb-history . 1))))
  2598.   (gud-overload-functions '((gud-massage-args . gud-perldb-massage-args)
  2599.                 (gud-marker-filter . gud-perldb-marker-filter)
  2600.                 (gud-find-file . gud-perldb-find-file)
  2601.                 ))
  2602.  
  2603.   (gud-common-init command-line "perldb")
  2604.  
  2605.   (gud-def gud-break  "b %l"         "\C-b" "Set breakpoint at current line.")
  2606.   (gud-def gud-remove "d %l"         "\C-d" "Remove breakpoint at current line")
  2607.   (gud-def gud-step   "s"            "\C-s" "Step one source line with display.")
  2608.   (gud-def gud-next   "n"            "\C-n" "Step one line (skip functions).")
  2609.   (gud-def gud-cont   "c"            "\C-r" "Continue with display.")
  2610. ;  (gud-def gud-finish "finish"       "\C-f" "Finish executing current function.")
  2611. ;  (gud-def gud-up     "up %p"        "<" "Up N stack frames (numeric arg).")
  2612. ;  (gud-def gud-down   "down %p"      ">" "Down N stack frames (numeric arg).")
  2613.   (gud-def gud-print  "%e"           "\C-p" "Evaluate perl expression at point.")
  2614.  
  2615.   (setq comint-prompt-regexp "^  DB<[0-9]+> ")
  2616.   (run-hooks 'perldb-mode-hook)
  2617.   )
  2618.  
  2619. ;;
  2620. ;; End of debugger-specific information
  2621. ;;
  2622.  
  2623.  
  2624. ;;; When we send a command to the debugger via gud-call, it's annoying
  2625. ;;; to see the command and the new prompt inserted into the debugger's
  2626. ;;; buffer; we have other ways of knowing the command has completed.
  2627. ;;;
  2628. ;;; If the buffer looks like this:
  2629. ;;; --------------------
  2630. ;;; (gdb) set args foo bar
  2631. ;;; (gdb) -!-
  2632. ;;; --------------------
  2633. ;;; (the -!- marks the location of point), and we type `C-x SPC' in a
  2634. ;;; source file to set a breakpoint, we want the buffer to end up like
  2635. ;;; this:
  2636. ;;; --------------------
  2637. ;;; (gdb) set args foo bar
  2638. ;;; Breakpoint 1 at 0x92: file make-docfile.c, line 49.
  2639. ;;; (gdb) -!-
  2640. ;;; --------------------
  2641. ;;; Essentially, the old prompt is deleted, and the command's output
  2642. ;;; and the new prompt take its place.
  2643. ;;;
  2644. ;;; Not echoing the command is easy enough; you send it directly using
  2645. ;;; comint-input-sender, and it never enters the buffer.  However,
  2646. ;;; getting rid of the old prompt is trickier; you don't want to do it
  2647. ;;; when you send the command, since that will result in an annoying
  2648. ;;; flicker as the prompt is deleted, redisplay occurs while Emacs
  2649. ;;; waits for a response from the debugger, and the new prompt is
  2650. ;;; inserted.  Instead, we'll wait until we actually get some output
  2651. ;;; from the subprocess before we delete the prompt.  If the command
  2652. ;;; produced no output other than a new prompt, that prompt will most
  2653. ;;; likely be in the first chunk of output received, so we will delete
  2654. ;;; the prompt and then replace it with an identical one.  If the
  2655. ;;; command produces output, the prompt is moving anyway, so the
  2656. ;;; flicker won't be annoying.
  2657. ;;;
  2658. ;;; So - when we want to delete the prompt upon receipt of the next
  2659. ;;; chunk of debugger output, we position gud-delete-prompt-marker at
  2660. ;;; the start of the prompt; the process filter will notice this, and
  2661. ;;; delete all text between it and the process output marker.  If
  2662. ;;; gud-delete-prompt-marker points nowhere, we leave the current
  2663. ;;; prompt alone.
  2664. (defvar gud-delete-prompt-marker nil)
  2665.  
  2666.  
  2667. (defvar gdbish-comint-mode-map (copy-keymap comint-mode-map))
  2668. (define-key gdbish-comint-mode-map "\C-c\M-\C-r" 'gud-display-registers-buffer)
  2669. (define-key gdbish-comint-mode-map "\C-c\M-\C-f" 'gud-display-stack-buffer)
  2670. (define-key gdbish-comint-mode-map "\C-c\M-\C-b" 'gud-display-breakpoints-buffer)
  2671.  
  2672. (defun gud-mode ()
  2673.   "Major mode for interacting with an inferior debugger process.
  2674.  
  2675.    You start it up with one of the commands M-x gdb, M-x sdb, M-x dbx,
  2676. or M-x xdb.  Each entry point finishes by executing a hook; `gdb-mode-hook',
  2677. `sdb-mode-hook', `dbx-mode-hook' or `xdb-mode-hook' respectively.
  2678.  
  2679. After startup, the following commands are available in both the GUD
  2680. interaction buffer and any source buffer GUD visits due to a breakpoint stop
  2681. or step operation:
  2682.  
  2683. \\[gud-break] sets a breakpoint at the current file and line.  In the
  2684. GUD buffer, the current file and line are those of the last breakpoint or
  2685. step.  In a source buffer, they are the buffer's file and current line.
  2686.  
  2687. \\[gud-remove] removes breakpoints on the current file and line.
  2688.  
  2689. \\[gud-refresh] displays in the source window the last line referred to
  2690. in the gud buffer.
  2691.  
  2692. \\[gud-step], \\[gud-next], and \\[gud-stepi] do a step-one-line,
  2693. step-one-line (not entering function calls), and step-one-instruction
  2694. and then update the source window with the current file and position.
  2695. \\[gud-cont] continues execution.
  2696.  
  2697. \\[gud-print] tries to find the largest C lvalue or function-call expression
  2698. around point, and sends it to the debugger for value display.
  2699.  
  2700. The above commands are common to all supported debuggers except xdb which
  2701. does not support stepping instructions.
  2702.  
  2703. Under gdb, sdb and xdb, \\[gud-tbreak] behaves exactly like \\[gud-break],
  2704. except that the breakpoint is temporary; that is, it is removed when
  2705. execution stops on it.
  2706.  
  2707. Under gdb, dbx, and xdb, \\[gud-up] pops up through an enclosing stack
  2708. frame.  \\[gud-down] drops back down through one.
  2709.  
  2710. If you are using gdb or xdb, \\[gud-finish] runs execution to the return from
  2711. the current function and stops.
  2712.  
  2713. All the keystrokes above are accessible in the GUD buffer
  2714. with the prefix C-c, and in all buffers through the prefix C-x C-a.
  2715.  
  2716. All pre-defined functions for which the concept make sense repeat
  2717. themselves the appropriate number of times if you give a prefix
  2718. argument.
  2719.  
  2720. You may use the `gud-def' macro in the initialization hook to define other
  2721. commands.
  2722.  
  2723. Other commands for interacting with the debugger process are inherited from
  2724. comint mode, which see."
  2725.   (interactive)
  2726.   (comint-mode)
  2727.   (setq major-mode 'gud-mode)
  2728.   (setq mode-name "Debugger")
  2729.   (setq mode-line-process '(": %s"))
  2730.   (use-local-map (copy-keymap gdbish-comint-mode-map))
  2731.   (setq gud-last-frame nil)
  2732.   (make-local-variable 'comint-prompt-regexp)
  2733.   (make-local-variable 'gud-delete-prompt-marker)
  2734.   (setq gud-delete-prompt-marker (make-marker))
  2735.   (run-hooks 'gud-mode-hook)
  2736. )
  2737.  
  2738. (defvar gud-comint-buffer nil)
  2739.  
  2740. ;; Chop STRING into words separated by SPC or TAB and return a list of them.
  2741. (defun gud-chop-words (string)
  2742.   (let ((i 0) (beg 0)
  2743.     (len (length string))
  2744.     (words nil))
  2745.     (while (< i len)
  2746.       (if (memq (aref string i) '(?\t ? ))
  2747.       (progn
  2748.         (setq words (cons (substring string beg i) words)
  2749.           beg (1+ i))
  2750.         (while (and (< beg len) (memq (aref string beg) '(?\t ? )))
  2751.           (setq beg (1+ beg)))
  2752.         (setq i (1+ beg)))
  2753.     (setq i (1+ i))))
  2754.     (if (< beg len)
  2755.     (setq words (cons (substring string beg) words)))
  2756.     (nreverse words)))
  2757.  
  2758. (defvar gud-target-name "--unknown--"
  2759.   "The apparent name of the program being debugged in a gud buffer.
  2760. For sure this the root string used in smashing together the gud 
  2761. buffer's name, even if that doesn't happen to be the name of a 
  2762. program.")
  2763.  
  2764. ;; Perform initializations common to all debuggers.
  2765. (defun gud-common-init (command-line debugger-name)
  2766.   (let* ((words (gud-chop-words command-line))
  2767.      (program (car words))
  2768.      (file-word (let ((w (cdr words)))
  2769.               (while (and w (= ?- (aref (car w) 0)))
  2770.             (setq w (cdr w)))
  2771.               (car w)))
  2772.      (args (delq file-word (cdr words)))
  2773.      (file (and file-word (expand-file-name file-word)))
  2774.      (filepart (if file (file-name-nondirectory file) ""))
  2775.      (buffer-name (concat "*" debugger-name 
  2776.                   (and (string< "" filepart) 
  2777.                    (concat "-" filepart)) "*")))
  2778.     (switch-to-buffer buffer-name)
  2779.     (if file
  2780.     (setq default-directory (file-name-directory file)))
  2781.     (or (bolp) (newline))
  2782.     (insert "Current directory is " default-directory "\n")
  2783.     (let ((old-instance gdb-buffer-instance))
  2784.       (apply 'make-comint (concat debugger-name
  2785.                   (and (string< "" filepart)
  2786.                        (concat "-" filepart))) 
  2787.          program nil
  2788.          ;; There *has* to be an easier way to strip "nil"s from the output
  2789.          ;; of gud-massage-args
  2790.          (apply 'append (mapcar '(lambda (arg) (if (stringp arg) (list arg) arg))
  2791.                     (gud-massage-args file args))))
  2792.       (gud-mode)
  2793.       (make-variable-buffer-local 'old-gdb-buffer-instance)
  2794.       (setq old-gdb-buffer-instance old-instance))
  2795.     (make-variable-buffer-local 'gud-target-name)
  2796.     (setq gud-target-name filepart))
  2797.   (set-process-filter (get-buffer-process (current-buffer)) 'gud-filter)
  2798.   (set-process-sentinel (get-buffer-process (current-buffer)) 'gud-sentinel)
  2799.   (gud-set-buffer)
  2800.   )
  2801.  
  2802. (defun gud-set-buffer ()
  2803.   (cond ((eq major-mode 'gud-mode)
  2804.     (setq gud-comint-buffer (current-buffer)))))
  2805.  
  2806. ;; These functions are responsible for inserting output from your debugger
  2807. ;; into the buffer.  The hard work is done by the method that is
  2808. ;; the value of gud-marker-filter.
  2809.  
  2810. (defun gud-filter (proc string)
  2811.   ;; Here's where the actual buffer insertion is done
  2812.   (let ((inhibit-quit t))
  2813.     (save-excursion
  2814.       (set-buffer (process-buffer proc))
  2815.       (let (moving output-after-point)
  2816.     (save-excursion
  2817.       (goto-char (process-mark proc))
  2818.       ;; If we have been so requested, delete the debugger prompt.
  2819.       (if (marker-buffer gud-delete-prompt-marker)
  2820.           (progn
  2821.         (delete-region (point) gud-delete-prompt-marker)
  2822.         (set-marker gud-delete-prompt-marker nil)))
  2823.       (insert-before-markers (gud-marker-filter string))
  2824.       (setq moving (= (point) (process-mark proc)))
  2825.       (setq output-after-point (< (point) (process-mark proc)))
  2826.       ;; Check for a filename-and-line number.
  2827.       ;; Don't display the specified file
  2828.       ;; unless (1) point is at or after the position where output appears
  2829.       ;; and (2) this buffer is on the screen.
  2830.       (if (and gud-last-frame
  2831.            (not output-after-point)
  2832.            (get-buffer-window (current-buffer)))
  2833.           (gud-display-frame)))
  2834.     (if moving (goto-char (process-mark proc)))))))
  2835.  
  2836. (defun gud-proc-died (proc)
  2837.   ;; Stop displaying an arrow in a source file.
  2838.   (setq overlay-arrow-position nil)
  2839.  
  2840.   ;; Kill the dummy process, so that C-x C-c won't worry about it.
  2841.   (save-excursion
  2842.     (set-buffer (process-buffer proc))
  2843.     (let ((buf (gdb-get-instance-buffer gdb-buffer-instance
  2844.                     'gdb-inferior-io)))
  2845.       (if buf
  2846.       (kill-process (get-buffer-process buf)))
  2847.       )))
  2848.  
  2849. (defun gud-sentinel (proc msg)
  2850.   (cond ((null (buffer-name (process-buffer proc)))
  2851.      ;; buffer killed
  2852.      (gud-proc-died proc)
  2853.      (set-process-buffer proc nil))
  2854.     ((memq (process-status proc) '(signal exit))
  2855.      (gud-proc-died proc)
  2856.  
  2857.      ;; Fix the mode line.
  2858.      (setq mode-line-process
  2859.            (concat ": "
  2860.                (symbol-name (process-status proc))))
  2861.      (let* ((obuf (current-buffer)))
  2862.        ;; save-excursion isn't the right thing if
  2863.        ;;  process-buffer is current-buffer
  2864.        (unwind-protect
  2865.            (progn
  2866.          ;; Write something in *compilation* and hack its mode line,
  2867.          (set-buffer (process-buffer proc))
  2868.          ;; Force mode line redisplay soon
  2869.          (set-buffer-modified-p (buffer-modified-p))
  2870.          (if (eobp)
  2871.              (insert ?\n mode-name " " msg)
  2872.            (save-excursion
  2873.              (goto-char (point-max))
  2874.              (insert ?\n mode-name " " msg)))
  2875.          ;; If buffer and mode line will show that the process
  2876.          ;; is dead, we can delete it now.  Otherwise it
  2877.          ;; will stay around until M-x list-processes.
  2878.          (delete-process proc))
  2879.          ;; Restore old buffer, but don't restore old point
  2880.          ;; if obuf is the gud buffer.
  2881.          (set-buffer obuf))))))
  2882.  
  2883. (defun gud-display-frame ()
  2884.   "Find and obey the last filename-and-line marker from the debugger.
  2885. Obeying it means displaying in another window the specified file and line."
  2886.   (interactive)
  2887.   (if gud-last-frame
  2888.    (progn
  2889. ;     (gud-set-buffer)
  2890.      (gud-display-line (car gud-last-frame) (cdr gud-last-frame))
  2891.      (setq gud-last-last-frame gud-last-frame
  2892.        gud-last-frame nil))))
  2893.  
  2894. ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
  2895. ;; and that its line LINE is visible.
  2896. ;; Put the overlay-arrow on the line LINE in that buffer.
  2897. ;; Most of the trickiness in here comes from wanting to preserve the current
  2898. ;; region-restriction if that's possible.  We use an explicit display-buffer
  2899. ;; to get around the fact that this is called inside a save-excursion.
  2900.  
  2901. (defun gud-display-line (true-file line)
  2902.   (let* ((buffer (gud-find-file true-file))
  2903.      (window (gud-display-source-buffer buffer))
  2904.      (pos))
  2905.     (if (not window)
  2906.     (error "foo bar baz"))
  2907. ;;;    (if (equal buffer (current-buffer))
  2908. ;;;    nil
  2909. ;;;      (setq buffer-read-only nil))
  2910.     (save-excursion
  2911. ;;;      (setq buffer-read-only t)
  2912.       (set-buffer buffer)
  2913.       (save-restriction
  2914.     (widen)
  2915.     (goto-line line)
  2916.     (setq pos (point))
  2917.     (setq overlay-arrow-string "=>")
  2918.     (or overlay-arrow-position
  2919.         (setq overlay-arrow-position (make-marker)))
  2920.     (set-marker overlay-arrow-position (point) (current-buffer)))
  2921.       (cond ((or (< pos (point-min)) (> pos (point-max)))
  2922.          (widen)
  2923.          (goto-char pos))))
  2924.     (set-window-point window overlay-arrow-position)))
  2925.  
  2926. ;;; The gud-call function must do the right thing whether its invoking
  2927. ;;; keystroke is from the GUD buffer itself (via major-mode binding)
  2928. ;;; or a C buffer.  In the former case, we want to supply data from
  2929. ;;; gud-last-frame.  Here's how we do it:
  2930.  
  2931. (defun gud-format-command (str arg)
  2932.   (let ((insource (not (eq (current-buffer) gud-comint-buffer))))
  2933.     (if (string-match "\\(.*\\)%f\\(.*\\)" str)
  2934.     (setq str (concat
  2935.            (substring str (match-beginning 1) (match-end 1))
  2936.            (file-name-nondirectory (if insource
  2937.                            (buffer-file-name)
  2938.                          (car gud-last-frame)))
  2939.            (substring str (match-beginning 2) (match-end 2)))))
  2940.     (if (string-match "\\(.*\\)%d\\(.*\\)" str)
  2941.     (setq str (concat
  2942.            (substring str (match-beginning 1) (match-end 1))
  2943.            (file-name-directory (if insource
  2944.                         (buffer-file-name)
  2945.                       (car gud-last-frame)))
  2946.            (substring str (match-beginning 2) (match-end 2)))))
  2947.     (if (string-match "\\(.*\\)%l\\(.*\\)" str)
  2948.     (setq str (concat
  2949.            (substring str (match-beginning 1) (match-end 1))
  2950.            (if insource
  2951.                (save-excursion
  2952.              (beginning-of-line)
  2953.              (save-restriction (widen) 
  2954.                        (1+ (count-lines 1 (point)))))
  2955.              (cdr gud-last-frame))
  2956.            (substring str (match-beginning 2) (match-end 2)))))
  2957.     (if (string-match "\\(.*\\)%e\\(.*\\)" str)
  2958.     (setq str (concat
  2959.            (substring str (match-beginning 1) (match-end 1))
  2960.            (find-c-expr)
  2961.            (substring str (match-beginning 2) (match-end 2)))))
  2962.     (if (string-match "\\(.*\\)%a\\(.*\\)" str)
  2963.     (setq str (concat
  2964.            (substring str (match-beginning 1) (match-end 1))
  2965.            (gud-read-address)
  2966.            (substring str (match-beginning 2) (match-end 2)))))
  2967.     (if (string-match "\\(.*\\)%p\\(.*\\)" str)
  2968.     (setq str (concat
  2969.            (substring str (match-beginning 1) (match-end 1))
  2970.            (if arg (int-to-string arg) "")
  2971.            (substring str (match-beginning 2) (match-end 2)))))
  2972.     )
  2973.   str
  2974.   )
  2975.  
  2976. (defun gud-read-address ()
  2977.   "Return a string containing the core-address found in the buffer at point."
  2978.   (save-excursion
  2979.     (let ((pt (point)) found begin)
  2980.       (setq found (if (search-backward "0x" (- pt 7) t) (point)))
  2981.       (cond
  2982.        (found (forward-char 2)
  2983.           (buffer-substring found
  2984.                 (progn (re-search-forward "[^0-9a-f]")
  2985.                        (forward-char -1)
  2986.                        (point))))
  2987.        (t (setq begin (progn (re-search-backward "[^0-9]") 
  2988.                  (forward-char 1)
  2989.                  (point)))
  2990.       (forward-char 1)
  2991.       (re-search-forward "[^0-9]")
  2992.       (forward-char -1)
  2993.       (buffer-substring begin (point)))))))
  2994.  
  2995. (defun gud-call (fmt &optional arg)
  2996.   (let ((msg (gud-format-command fmt arg)))
  2997.     (message "Command: %s" msg)
  2998.     (sit-for 0)
  2999.     (gud-basic-call msg)))
  3000.  
  3001. (defun gud-basic-call (command)
  3002.   "Invoke the debugger COMMAND displaying source in other window."
  3003.   (interactive)
  3004.   (gud-set-buffer)
  3005.   (let ((proc (get-buffer-process gud-comint-buffer)))
  3006.  
  3007.     ;; Arrange for the current prompt to get deleted.
  3008.     (save-excursion
  3009.       (set-buffer gud-comint-buffer)
  3010.       (goto-char (process-mark proc))
  3011.       (beginning-of-line)
  3012.       (if (looking-at comint-prompt-regexp)
  3013.       (set-marker gud-delete-prompt-marker (point)))
  3014.       (apply comint-input-sender (list proc command)))))
  3015.  
  3016. (defun gud-refresh (&optional arg)
  3017.   "Fix up a possibly garbled display, and redraw the arrow."
  3018.   (interactive "P")
  3019.   (recenter arg)
  3020.   (or gud-last-frame (setq gud-last-frame gud-last-last-frame))
  3021.   (gud-display-frame))
  3022.  
  3023. ;;; Count windows on a given frame
  3024. ;;
  3025. (defun count-frame-windows (frame &optional minibuf)
  3026.   "Returns the number of visible windows on FRAME.
  3027. Optional arg NO-MINI non-nil means don't count the minibuffer
  3028. even if it is active."
  3029.   (let ((count 0))
  3030.     (walk-windows (function (lambda (w)
  3031.                   (if (eq (window-frame w) frame)
  3032.                   (setq count (+ count 1)))))
  3033.           minibuf t)
  3034.     count))
  3035.  
  3036.  
  3037. ;; Attempt to fit a frame so that it is just large enough to display buf
  3038. ;; Only changes the frame size if it has just one window and we can only
  3039. ;; make the attempt if the buffer has truncate-lines set (otherwise it's
  3040. ;; too painful to work out how many lines we need.
  3041. ;; Doesn't even *attempt* to cope with fontified buffers.
  3042.  
  3043. (defun fit-frame-to-buffer (frame buf)
  3044.   (let (height-needed)
  3045.     (if (and frame 
  3046.          truncate-lines 
  3047.          (<= (count-frame-windows frame) 1))
  3048.     (progn 
  3049.       (setq height-needed 
  3050.         (+ (count-lines (point-min) (point-max)) 2))
  3051.       (cond 
  3052.        ((> (frame-height frame) height-needed)
  3053.         (set-frame-height frame height-needed))
  3054.        ((< height-needed 24)
  3055.         (set-frame-height frame height-needed))
  3056.        (t
  3057.         (set-frame-height frame 24)))))))
  3058.  
  3059. ;;; Code for parsing expressions out of C code.  The single entry point is
  3060. ;;; find-c-expr, which tries to return an lvalue expression from around point.
  3061. ;;;
  3062. ;;; The rest of this file is a hacked version of gdbsrc.el by
  3063. ;;; Debby Ayers <ayers@asc.slb.com>,
  3064. ;;; Rich Schaefer <schaefer@asc.slb.com> Schlumberger, Austin, Tx.
  3065.  
  3066. (defun find-c-expr ()
  3067.   "Returns the C expr that surrounds point."
  3068.   (interactive)
  3069.   (save-excursion
  3070.     (let ((p) (expr) (test-expr))
  3071.       (setq p (point))
  3072.       (setq expr (expr-cur))
  3073.       (setq test-expr (expr-prev))
  3074.       (while (expr-compound test-expr expr)
  3075.     (setq expr (cons (car test-expr) (cdr expr)))
  3076.     (goto-char (car expr))
  3077.     (setq test-expr (expr-prev)))
  3078.       (goto-char p)
  3079.       (setq test-expr (expr-next))
  3080.       (while (expr-compound expr test-expr)
  3081.     (setq expr (cons (car expr) (cdr test-expr)))
  3082.     (setq test-expr (expr-next))
  3083.     )
  3084.       (buffer-substring (car expr) (cdr expr)))))
  3085.  
  3086. (defun expr-cur ()
  3087.   "Returns the expr that point is in; point is set to beginning of expr.
  3088. The expr is represented as a cons cell, where the car specifies the point in
  3089. the current buffer that marks the beginning of the expr and the cdr specifies 
  3090. the character after the end of the expr."
  3091.   (let ((p (point)) (begin) (end))
  3092.     (expr-backward-sexp)
  3093.     (setq begin (point))
  3094.     (expr-forward-sexp)
  3095.     (setq end (point))
  3096.     (if (>= p end) 
  3097.     (progn
  3098.      (setq begin p)
  3099.      (goto-char p)
  3100.      (expr-forward-sexp)
  3101.      (setq end (point))
  3102.      )
  3103.       )
  3104.     (goto-char begin)
  3105.     (cons begin end)))
  3106.  
  3107. (defun expr-backward-sexp ()
  3108.   "Version of `backward-sexp' that catches errors."
  3109.   (condition-case nil
  3110.       (backward-sexp)
  3111.     (error t)))
  3112.  
  3113. (defun expr-forward-sexp ()
  3114.   "Version of `forward-sexp' that catches errors."
  3115.   (condition-case nil
  3116.      (forward-sexp)
  3117.     (error t)))
  3118.  
  3119. (defun expr-prev ()
  3120.   "Returns the previous expr, point is set to beginning of that expr.
  3121. The expr is represented as a cons cell, where the car specifies the point in
  3122. the current buffer that marks the beginning of the expr and the cdr specifies 
  3123. the character after the end of the expr"
  3124.   (let ((begin) (end))
  3125.     (expr-backward-sexp)
  3126.     (setq begin (point))
  3127.     (expr-forward-sexp)
  3128.     (setq end (point))
  3129.     (goto-char begin)
  3130.     (cons begin end)))
  3131.  
  3132. (defun expr-next ()
  3133.   "Returns the following expr, point is set to beginning of that expr.
  3134. The expr is represented as a cons cell, where the car specifies the point in
  3135. the current buffer that marks the beginning of the expr and the cdr specifies 
  3136. the character after the end of the expr."
  3137.   (let ((begin) (end))
  3138.     (expr-forward-sexp)
  3139.     (expr-forward-sexp)
  3140.     (setq end (point))
  3141.     (expr-backward-sexp)
  3142.     (setq begin (point))
  3143.     (cons begin end)))
  3144.  
  3145. (defun expr-compound-sep (span-start span-end)
  3146.   "Returns '.' for '->' & '.', returns ' ' for white space,
  3147. returns '?' for other punctuation."
  3148.   (let ((result ? )
  3149.     (syntax))
  3150.     (while (< span-start span-end)
  3151.       (setq syntax (char-syntax (char-after span-start)))
  3152.       (cond
  3153.        ((= syntax ? ) t)
  3154.        ((= syntax ?.) (setq syntax (char-after span-start))
  3155.     (cond 
  3156.      ((= syntax ?.) (setq result ?.))
  3157.      ((and (= syntax ?-) (= (char-after (+ span-start 1)) ?>))
  3158.       (setq result ?.)
  3159.       (setq span-start (+ span-start 1)))
  3160.      (t (setq span-start span-end)
  3161.         (setq result ??)))))
  3162.       (setq span-start (+ span-start 1)))
  3163.     result))
  3164.  
  3165. (defun expr-compound (first second)
  3166.   "Non-nil if concatenating FIRST and SECOND makes a single C token.
  3167. The two exprs are represented as a cons cells, where the car 
  3168. specifies the point in the current buffer that marks the beginning of the 
  3169. expr and the cdr specifies the character after the end of the expr.
  3170. Link exprs of the form:
  3171.       Expr -> Expr
  3172.       Expr . Expr
  3173.       Expr (Expr)
  3174.       Expr [Expr]
  3175.       (Expr) Expr
  3176.       [Expr] Expr"
  3177.   (let ((span-start (cdr first))
  3178.     (span-end (car second))
  3179.     (syntax))
  3180.     (setq syntax (expr-compound-sep span-start span-end))
  3181.     (cond
  3182.      ((= (car first) (car second)) nil)
  3183.      ((= (cdr first) (cdr second)) nil)
  3184.      ((= syntax ?.) t)
  3185.      ((= syntax ? )
  3186.      (setq span-start (char-after (- span-start 1)))
  3187.      (setq span-end (char-after span-end))
  3188.      (cond
  3189.       ((= span-start ?) ) t )
  3190.       ((= span-start ?] ) t )
  3191.           ((= span-end ?( ) t )
  3192.       ((= span-end ?[ ) t )
  3193.       (t nil))
  3194.      )
  3195.      (t nil))))
  3196.  
  3197.  
  3198. ;;; Compare two buffers. We assume that they're not narrowed.
  3199. (defun gud-buffers-differ (buffer1 buffer2)
  3200.   (save-excursion
  3201.     (let ((size1 (progn (set-buffer buffer1) (buffer-size)))
  3202.       (size2 (progn (set-buffer buffer2) (buffer-size))))
  3203.       (cond
  3204.        ((not (= size1 size2))
  3205.     t)
  3206.        ((= (compare-buffer-substrings 
  3207.         buffer1 1 size1
  3208.         buffer2 1 size2) 0)
  3209.     nil)
  3210.        (t)))))
  3211.  
  3212.  
  3213. (provide 'gud)
  3214.  
  3215. ;; WTF
  3216. (defmacro gud (form)
  3217.   (` (save-excursion (set-buffer "*gud-a.out*") (, form))))
  3218.  
  3219. (defun dbug (foo &optional fun)
  3220.   (save-excursion
  3221.     (set-buffer (get-buffer-create "*trace*"))
  3222.     (goto-char (point-max))
  3223.     (insert "***" (symbol-name foo) "\n")
  3224.     (if fun
  3225.     (funcall fun))))
  3226.  
  3227.  
  3228.  
  3229. ;;; gud.el ends here
  3230.